Compose include composable e modificatori integrati per la gestione dei casi d'uso comuni delle animazioni.
Composable animati integrati
Compose fornisce diversi composable che animano l'aspetto, la scomparsa e le modifiche al layout dei contenuti.
Animare la comparsa e la scomparsa
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 ed espansione e scompaiono con
dissolvenza in uscita e riduzione. Personalizza questa transizione specificando gli oggetti
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 mostrato nell'esempio precedente, puoi combinare più oggetti EnterTransition o ExitTransition con un operatore + e ognuno accetta parametri facoltativi per personalizzare il proprio comportamento. Per ulteriori informazioni, consulta le pagine di riferimento.
Esempi di transizioni di entrata e uscita
AnimatedVisibility offre anche una variante che accetta un argomento
MutableTransitionState. In questo modo puoi attivare un'animazione non appena
il composable 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 che AnimatedVisibility non applichi alcuna animazione
in modo che gli elementi secondari possano avere animazioni distinte
animateEnterExit. Per farlo, specifica EnterTransition.None e
ExitTransition.None nel componibile 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 utilizzando la proprietà transition
all'interno della lambda di contenuti per AnimatedVisibility. Gli stati di animazione
aggiunti all'istanza di transizione verranno eseguiti 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 composable dei contenuti 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 scoprire di più sull'utilizzo di Transition per gestire le animazioni, consulta Animare
più proprietà contemporaneamente con una transizione.
Animare in base allo stato di destinazione
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") } }
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 un'istanza di ContentTransform combinando un oggetto EnterTransition con un oggetto ExitTransition utilizzando la funzione infissa with. Puoi applicare SizeTransform
all'oggetto ContentTransform collegandolo 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.
Si tratta di alternative pratiche a slideInHorizontally/Vertically e
slideOutHorizontally/Vertically che calcolano la distanza di scorrimento in base
alle dimensioni dei contenuti iniziali e di quelli 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
Proprio 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 il passaggio tra due layout
Crossfade esegue la transizione 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
Compose fornisce modificatori per animare modifiche specifiche direttamente sui composables.
Animare le modifiche delle dimensioni dei componenti componibili
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 di layout pigro.
Consigliati per te
- Nota: il testo del link viene visualizzato quando JavaScript è disattivato
- Animazioni basate sul valore
- Animazioni in Compose
- Supporto degli strumenti di animazione {:#tooling}