Compose è dotato di composable e modificatori integrati per la gestione dei casi d'uso comuni delle animazioni.
Componenti animati integrati
Animare la comparsa e la scomparsa con AnimatedVisibility

Il
AnimatedVisibility
composable anima la comparsa e la scomparsa dei suoi contenuti.
var visible by remember { mutableStateOf(true) } // Animated visibility will eventually remove the item from the composition once the animation has finished. AnimatedVisibility(visible) { // your composable here // ... }
Per impostazione predefinita, i contenuti vengono visualizzati con dissolvenza in entrata e espansione e scompaiono con
dissolvenza in uscita e riduzione. La transizione può essere personalizzata specificando
EnterTransition
e
ExitTransition
.
var visible by remember { mutableStateOf(true) } val density = LocalDensity.current AnimatedVisibility( visible = visible, enter = slideInVertically { // Slide in from 40 dp from the top. with(density) { -40.dp.roundToPx() } } + expandVertically( // Expand from the top. expandFrom = Alignment.Top ) + fadeIn( // Fade in with the initial alpha of 0.3f. initialAlpha = 0.3f ), exit = slideOutVertically() + shrinkVertically() + fadeOut() ) { Text( "Hello", Modifier .fillMaxWidth() .height(200.dp) ) }
Come puoi vedere nell'esempio precedente, puoi combinare più oggetti EnterTransition
o ExitTransition
con un operatore +
e ognuno accetta parametri facoltativi per personalizzarne il comportamento. Per ulteriori informazioni, consulta i riferimenti.
Esempi di EnterTransition
e ExitTransition
AnimatedVisibility
offre anche una variante che accetta un
MutableTransitionState
. In questo modo, puoi attivare un'animazione non appena
AnimatedVisibility
viene aggiunto all'albero di composizione. È utile anche per
osservare lo stato dell'animazione.
// Create a MutableTransitionState<Boolean> for the AnimatedVisibility. val state = remember { MutableTransitionState(false).apply { // Start the animation immediately. targetState = true } } Column { AnimatedVisibility(visibleState = state) { Text(text = "Hello, world!") } // Use the MutableTransitionState to know the current animation state // of the AnimatedVisibility. Text( text = when { state.isIdle && state.currentState -> "Visible" !state.isIdle && state.currentState -> "Disappearing" state.isIdle && !state.currentState -> "Invisible" else -> "Appearing" } ) }
Animare l'entrata e l'uscita per i bambini
I contenuti all'interno di AnimatedVisibility
(elementi secondari diretti o indiretti) possono utilizzare il modificatore
animateEnterExit
per specificare un comportamento di animazione diverso per ciascuno. L'effetto
visivo per ciascuno di questi elementi secondari è una combinazione delle animazioni specificate
nel composable AnimatedVisibility
e delle animazioni di entrata e
uscita dell'elemento secondario.
var visible by remember { mutableStateOf(true) } AnimatedVisibility( visible = visible, enter = fadeIn(), exit = fadeOut() ) { // Fade in/out the background and the foreground. Box( Modifier .fillMaxSize() .background(Color.DarkGray) ) { Box( Modifier .align(Alignment.Center) .animateEnterExit( // Slide in/out the inner box. enter = slideInVertically(), exit = slideOutVertically() ) .sizeIn(minWidth = 256.dp, minHeight = 64.dp) .background(Color.Red) ) { // Content of the notification… } } }
In alcuni casi, potresti voler fare in modo che AnimatedVisibility
non applichi alcuna animazione
in modo che gli elementi secondari possano avere animazioni distinte
animateEnterExit
. Per ottenere questo risultato, specifica EnterTransition.None
e
ExitTransition.None
nel composable AnimatedVisibility
.
Aggiungere un'animazione personalizzata
Se vuoi aggiungere effetti di animazione personalizzati oltre alle animazioni di entrata e uscita
integrate, accedi all'istanza Transition
sottostante tramite la proprietà transition
all'interno della lambda di contenuti per AnimatedVisibility
. Qualsiasi stato di animazione
aggiunto all'istanza di transizione verrà eseguito contemporaneamente alle animazioni di entrata
e uscita di AnimatedVisibility
. AnimatedVisibility
attende che
tutte le animazioni in Transition
siano terminate prima di rimuovere i relativi contenuti.
Per le animazioni di uscita create indipendentemente da Transition
(ad esempio utilizzando
animate*AsState
), AnimatedVisibility
non sarebbe in grado di tenerne conto e pertanto potrebbe rimuovere il contenuto componibile prima che termini.
var visible by remember { mutableStateOf(true) } AnimatedVisibility( visible = visible, enter = fadeIn(), exit = fadeOut() ) { // this: AnimatedVisibilityScope // Use AnimatedVisibilityScope#transition to add a custom animation // to the AnimatedVisibility. val background by transition.animateColor(label = "color") { state -> if (state == EnterExitState.Visible) Color.Blue else Color.Gray } Box( modifier = Modifier .size(128.dp) .background(background) ) }
Per i dettagli su Transition
, consulta updateTransition.
Animare in base allo stato di destinazione con AnimatedContent
Il componente AnimatedContent
anima i suoi contenuti man mano che cambiano in base a uno
stato di destinazione.
Row { var count by remember { mutableIntStateOf(0) } Button(onClick = { count++ }) { Text("Add") } AnimatedContent( targetState = count, label = "animated content" ) { targetCount -> // Make sure to use `targetCount`, not `count`. Text(text = "Count: $targetCount") } }
Tieni presente che devi sempre utilizzare il parametro lambda e rifletterlo nei contenuti. L'API utilizza questo valore come chiave per identificare i contenuti attualmente visualizzati.
Per impostazione predefinita, i contenuti iniziali vengono dissolti e poi i contenuti di destinazione vengono visualizzati in dissolvenza in entrata
(questo comportamento è chiamato dissolvenza incrociata). Puoi personalizzare questo comportamento dell'animazione specificando un oggetto ContentTransform
per il parametro transitionSpec
. Puoi creare ContentTransform
combinando un
EnterTransition
con un ExitTransition
utilizzando la funzione infissa with
. Puoi applicare SizeTransform
a ContentTransform
allegandolo con la
funzione infissa using
.
AnimatedContent( targetState = count, transitionSpec = { // Compare the incoming number with the previous number. if (targetState > initialState) { // If the target number is larger, it slides up and fades in // while the initial (smaller) number slides up and fades out. slideInVertically { height -> height } + fadeIn() togetherWith slideOutVertically { height -> -height } + fadeOut() } else { // If the target number is smaller, it slides down and fades in // while the initial number slides down and fades out. slideInVertically { height -> -height } + fadeIn() togetherWith slideOutVertically { height -> height } + fadeOut() }.using( // Disable clipping since the faded slide-in/out should // be displayed out of bounds. SizeTransform(clip = false) ) }, label = "animated content" ) { targetCount -> Text(text = "$targetCount") }
EnterTransition
definisce l'aspetto dei contenuti di destinazione e
ExitTransition
definisce la modalità di scomparsa dei contenuti iniziali. Oltre a tutte le funzioni EnterTransition
e ExitTransition
disponibili per AnimatedVisibility
, AnimatedContent
offre slideIntoContainer
e slideOutOfContainer
.
Queste sono alternative pratiche a slideInHorizontally/Vertically
e
slideOutHorizontally/Vertically
che calcolano la distanza della slide in base alle dimensioni dei contenuti iniziali e dei contenuti di destinazione dei contenuti
AnimatedContent
.
SizeTransform
definisce il modo in cui
le dimensioni devono animarsi tra i contenuti iniziali e quelli di destinazione. Quando crei l'animazione, hai accesso sia alle dimensioni iniziali sia a quelle di destinazione. SizeTransform
controlla anche se i contenuti devono essere ritagliati
in base alle dimensioni del componente durante le animazioni.
var expanded by remember { mutableStateOf(false) } Surface( color = MaterialTheme.colorScheme.primary, onClick = { expanded = !expanded } ) { AnimatedContent( targetState = expanded, transitionSpec = { fadeIn(animationSpec = tween(150, 150)) togetherWith fadeOut(animationSpec = tween(150)) using SizeTransform { initialSize, targetSize -> if (targetState) { keyframes { // Expand horizontally first. IntSize(targetSize.width, initialSize.height) at 150 durationMillis = 300 } } else { keyframes { // Shrink vertically first. IntSize(initialSize.width, targetSize.height) at 150 durationMillis = 300 } } } }, label = "size transform" ) { targetExpanded -> if (targetExpanded) { Expanded() } else { ContentIcon() } } }
Animare le transizioni di entrata e uscita dei figli
Come AnimatedVisibility
, il modificatore animateEnterExit
è disponibile all'interno della lambda dei contenuti di AnimatedContent
. Utilizza questo
per applicare EnterAnimation
e ExitAnimation
a ciascuno dei figli diretti o indiretti
separatamente.
Aggiungere un'animazione personalizzata
Come AnimatedVisibility
, il campo transition
è disponibile all'interno della
lambda dei contenuti di AnimatedContent
. Utilizza questa opzione per creare un effetto di animazione personalizzato
che viene eseguito contemporaneamente alla transizione AnimatedContent
. Per i dettagli, consulta
updateTransition.
Animare la transizione tra due layout con Crossfade
Crossfade
esegue l'animazione tra due layout con un'animazione di dissolvenza incrociata. Se attivi/disattivi
il valore passato al parametro current
, i contenuti vengono cambiati con un'animazione
di dissolvenza incrociata.
var currentPage by remember { mutableStateOf("A") } Crossfade(targetState = currentPage, label = "cross fade") { screen -> when (screen) { "A" -> Text("Page A") "B" -> Text("Page B") } }
Modificatori di animazione integrati
Animare le modifiche delle dimensioni dei componenti componibili con animateContentSize

Il modificatore animateContentSize
anima una modifica delle dimensioni.
var expanded by remember { mutableStateOf(false) } Box( modifier = Modifier .background(colorBlue) .animateContentSize() .height(if (expanded) 400.dp else 200.dp) .fillMaxWidth() .clickable( interactionSource = remember { MutableInteractionSource() }, indication = null ) { expanded = !expanded } ) { }
Animazioni delle voci di elenco
Se vuoi animare il riordino degli elementi all'interno di un elenco o di una griglia pigra, consulta la documentazione sull'animazione degli elementi del layout pigro.
Consigliati per te
- Nota: il testo del link viene visualizzato quando JavaScript è disattivato
- Animazioni basate sul valore
- Animazioni in Compose
- Supporto per gli strumenti di animazione {:#tooling}