Compose enthält integrierte zusammensetzbare Funktionen und Modifikatoren für häufige Animationsanwendungsfälle.
Integrierte animierte zusammensetzbare Funktionen
Erscheinen und Verschwinden mit AnimatedVisibility
animieren
Die zusammensetzbare Funktion AnimatedVisibility
animiert das Erscheinen und Verschwinden ihrer Inhalte.
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 // ... }
Standardmäßig wird der Inhalt eingeblendet, indem er ein- und maximiert wird, und wieder ausgeblendet, indem er aus- und verkleinert wird. Die Umstellung kann durch Angabe von EnterTransition
und ExitTransition
angepasst werden.
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)) }
Wie im obigen Beispiel gezeigt, können mehrere EnterTransition
- oder ExitTransition
-Objekte mit einem +
-Operator kombiniert werden. Jedes Objekt akzeptiert optionale Parameter, um sein Verhalten anzupassen. Weitere Informationen finden Sie in den Referenzen.
Beispiele für EnterTransition
und ExitTransition
AnimatedVisibility
bietet auch eine Variante an, für die ein MutableTransitionState
-Objekt verwendet wird. So können Sie eine Animation auslösen, sobald AnimatedVisibility
dem Zusammensetzungsbaum hinzugefügt wurde. Sie ist auch hilfreich, um den Animationsstatus zu beobachten.
// 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" } ) }
Ein- und Ausgang für Kinder animieren
Für Inhalte in AnimatedVisibility
(direkte oder indirekte untergeordnete Elemente) kann mit dem Modifikator animateEnterExit
jeweils ein anderes Animationsverhalten festgelegt werden. Der visuelle Effekt für jedes dieser untergeordneten Elemente ist eine Kombination aus den in der zusammensetzbaren Funktion AnimatedVisibility
angegebenen Animationen und den eigenen Einstiegs- und Exit-Animationen des Kindes.
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 einigen Fällen kann es sinnvoll sein, dass AnimatedVisibility
überhaupt keine Animationen anwendet, sodass jedes Kind über animateEnterExit
eigene Animationen erstellen kann. Geben Sie dazu bei der zusammensetzbaren Funktion AnimatedVisibility
EnterTransition.None
und ExitTransition.None
an.
Benutzerdefinierte Animation hinzufügen
Wenn Sie neben den integrierten Eingabe- und Exit-Animationen benutzerdefinierte Animationseffekte hinzufügen möchten, greifen Sie über das Attribut transition
in der Inhalts-Lambda-Funktion für AnimatedVisibility
auf die zugrunde liegende Transition
-Instanz zu. Alle Animationsstatus, die der Übergangsinstanz hinzugefügt werden, werden gleichzeitig mit den Eingabe- und Exit-Animationen von AnimatedVisibility
ausgeführt. AnimatedVisibility
wartet, bis alle Animationen im Transition
-Element beendet sind, bevor sein Inhalt entfernt wird.
Bei Exit-Animationen, die unabhängig von Transition
erstellt wurden (z. B. mit animate*AsState
), kann AnimatedVisibility
diese nicht berücksichtigen und entfernt daher möglicherweise die zusammensetzbare Funktion, bevor sie fertig ist.
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)) }
Weitere Informationen zu Transition
finden Sie unter updateTransition.
Mit AnimatedContent
basierend auf dem Zielstatus animieren
Der Inhalt der zusammensetzbaren Funktion AnimatedContent
animiert sich, wenn er sich in Abhängigkeit vom Zielstatus ändert.
Row { var count by remember { mutableStateOf(0) } Button(onClick = { count++ }) { Text("Add") } AnimatedContent(targetState = count) { targetCount -> // Make sure to use `targetCount`, not `count`. Text(text = "Count: $targetCount") } }
Sie sollten immer den Lambda-Parameter verwenden und im Inhalt widerspiegeln. Die API verwendet diesen Wert als Schlüssel, um den aktuell angezeigten Inhalt zu identifizieren.
Standardmäßig wird der ursprüngliche Inhalt ausgeblendet und dann der Zielinhalt eingeblendet. Dieses Verhalten wird als Überblenden bezeichnet. Sie können dieses Animationsverhalten anpassen, indem Sie ein ContentTransform
-Objekt für den transitionSpec
-Parameter angeben. Sie können ContentTransform
erstellen, indem Sie EnterTransition
mit einem ExitTransition
mithilfe der Infix-Funktion with
kombinieren. Sie können SizeTransform
auf ContentTransform
anwenden, indem Sie es mit der Infix-Funktion using
anhängen.
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() with 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() with slideOutVertically { height -> height } + fadeOut() }.using( // Disable clipping since the faded slide-in/out should // be displayed out of bounds. SizeTransform(clip = false) ) } ) { targetCount -> Text(text = "$targetCount") }
EnterTransition
definiert, wie der Zielinhalt erscheinen soll, und ExitTransition
definiert, wie der ursprüngliche Inhalt ausgeblendet werden soll. Zusätzlich zu allen für AnimatedVisibility
verfügbaren Funktionen EnterTransition
und ExitTransition
bietet AnimatedContent
slideIntoContainer
und slideOutOfContainer
.
Dies sind praktische Alternativen zu slideInHorizontally/Vertically
und slideOutHorizontally/Vertically
, bei denen der Abstand zwischen den Folien anhand der Größe des Anfangsinhalts und des Zielinhalts des AnimatedContent
-Inhalts berechnet wird.
Mit SizeTransform
wird definiert, wie die Größe zwischen dem ursprünglichen und dem Zielinhalt animiert wird. Beim Erstellen der Animation können Sie sowohl auf die Anfangs- als auch auf die Zielgröße zugreifen. Mit SizeTransform
wird auch festgelegt, ob der Inhalt bei Animationen auf die Komponentengröße zugeschnitten werden soll.
var expanded by remember { mutableStateOf(false) } Surface( color = MaterialTheme.colorScheme.primary, onClick = { expanded = !expanded } ) { AnimatedContent( targetState = expanded, transitionSpec = { fadeIn(animationSpec = tween(150, 150)) with 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 } } } } ) { targetExpanded -> if (targetExpanded) { Expanded() } else { ContentIcon() } } }
Animieren untergeordneter Ein- und Ausstiegsübergänge
Genau wie AnimatedVisibility
ist der animateEnterExit
-Modifikator in der Inhalts-Lambda-Funktion von AnimatedContent
verfügbar. Damit können Sie EnterAnimation
und ExitAnimation
separat auf die direkten oder indirekten untergeordneten Elemente anwenden.
Benutzerdefinierte Animation hinzufügen
Genau wie AnimatedVisibility
ist das Feld transition
innerhalb der Inhalts-Lambda-Funktion von AnimatedContent
verfügbar. Damit können Sie einen benutzerdefinierten Animationseffekt erstellen, der zeitgleich mit dem AnimatedContent
-Übergang ausgeführt wird. Weitere Informationen finden Sie unter updateTransition.
Mit Crossfade
zwischen zwei Layouts animieren
Crossfade
wird mit einer Überblendungsanimation zwischen zwei Layouts animiert. Durch Umschalten des Werts, der an den current
-Parameter übergeben wird, wird der Inhalt mit einer Überblendungsanimation ausgetauscht.
var currentPage by remember { mutableStateOf("A") } Crossfade(targetState = currentPage) { screen -> when (screen) { "A" -> Text("Page A") "B" -> Text("Page B") } }
Integrierte Animationsmodifikatoren
Größenänderungen bei zusammensetzbaren Funktionen mit animateContentSize
animieren
Der animateContentSize
-Modifikator animiert eine Größenänderung.
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 } ) { }
Animationen von Listeneinträgen
Wenn Sie die Neuanordnung von Elementen in einer Lazy-Liste oder einem Raster animieren möchten, sehen Sie sich die Dokumentation zur Animation von Lazy-Layout-Elementen an.
Empfehlungen für dich
- Hinweis: Der Linktext wird angezeigt, wenn JavaScript deaktiviert ist.
- Wertbezogene Animationen
- Animationen in der Funktion „Compose“
- Unterstützung für Animationstools {:#tooling}