Compose verfügt über integrierte zusammensetzbare Funktionen und Modifikatoren für gängige Anwendungsfälle in der Animation.
Integrierte animierte zusammensetzbare Funktionen
Aussehen und Verschwinden mit AnimatedVisibility
animieren
<ph type="x-smartling-placeholder">
Die
AnimatedVisibility
componable animiert das Erscheinungsbild und das Verschwinden seines Inhalts.
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 durch Ein- und Ausblenden eingeblendet und wieder ausgeblendet,
immer kleiner wird. Der Übergang kann angepasst werden, indem
EnterTransition
und
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)) }
Wie Sie im obigen Beispiel sehen, können Sie mehrere EnterTransition
-Elemente
oder ExitTransition
-Objekte mit einem +
-Operator an und akzeptiert für jedes optionale
um das Verhalten anzupassen. Weitere Informationen finden Sie in den Referenzen.
Beispiele für EnterTransition
und ExitTransition
AnimatedVisibility
bietet auch eine Variante mit einer
MutableTransitionState
. So können Sie eine Animation auslösen, sobald der
AnimatedVisibility
wird dem Kompositionsbaum hinzugefügt. Sie ist auch nützlich für
den Animationsstatus 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
Inhalte unter AnimatedVisibility
(direkte oder indirekte Kinder) dürfen die
animateEnterExit
, um für jeden ein anderes Animationsverhalten anzugeben. Das visuelle Element
für jedes dieser untergeordneten Elemente eine Kombination der angegebenen Animationen ist.
an der zusammensetzbaren Funktion AnimatedVisibility
und den eigenen Eingabe- und
zum Beenden von Animationen.
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
keine Animationen
sodass Kinder ihre eigenen Animationen haben können,
animateEnterExit
. Geben Sie dazu EnterTransition.None
und
ExitTransition.None
für die zusammensetzbare Funktion AnimatedVisibility
Benutzerdefinierte Animation hinzufügen
Wenn Sie benutzerdefinierte Animationseffekte hinzufügen möchten, die über die integrierten Ein- und Exit-Funktionen hinausgehen,
Animationen verwenden, greifen Sie über die transition
auf die zugrunde liegende Transition
-Instanz zu.
innerhalb der Inhalts-Lambda-Funktion für AnimatedVisibility
. Beliebige Animationen
Status, die der Transition-Instanz hinzugefügt wurden, werden gleichzeitig mit der Eingabetaste ausgeführt
und die Animationen von AnimatedVisibility
beenden. AnimatedVisibility
wartet bis
Alle Animationen im Transition
sind beendet, bevor der Inhalt entfernt wurde.
Für Exit-Animationen, die unabhängig von Transition
erstellt wurden (z. B. mit
animate*AsState
), AnimatedVisibility
kann diesen Vorgang nicht berücksichtigen,
und kann daher den zusammensetzbaren Inhalt entfernen, bevor er 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
Die AnimatedContent
Die Funktion animiert den Inhalt,
während er sich basierend auf
Zielstatus
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") } }
Beachten Sie, dass Sie immer den Lambda-Parameter verwenden und ihn im Inhalte. Die API verwendet diesen Wert als Schlüssel, um den Inhalt zu identifizieren, angezeigt wird.
Standardmäßig wird der ursprüngliche Inhalt ausgeblendet und dann der Zielinhalt ausgeblendet
Dieses Verhalten wird als Überblenden bezeichnet. Ich
können Sie dieses Animationsverhalten anpassen, indem Sie ein ContentTransform
-Objekt für den
transitionSpec
-Parameter. Sie können ContentTransform
erstellen, indem Sie
EnterTransition
mit einem ExitTransition
mit der Infix-Funktion with
. Sie können SizeTransform
anwenden
an die ContentTransform
durch Anhängen mit dem
Infix-Funktion 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() 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 angezeigt werden soll, und
ExitTransition
legt fest, wie der ursprüngliche Inhalt verschwinden soll. Außerdem
EnterTransition
- und ExitTransition
-Funktionen, die für
AnimatedVisibility
, AnimatedContent
Angebote slideIntoContainer
und slideOutOfContainer
.
Dies sind praktische Alternativen zu slideInHorizontally/Vertically
und
slideOutHorizontally/Vertically
, die die Entfernung der Folie berechnen anhand
die Größen des ursprünglichen Inhalts und des Zielinhalts
AnimatedContent
Inhalt.
SizeTransform
definiert, wie die
sollte zwischen dem anfänglichen Inhalt und dem Zielinhalt animiert werden. Du hast
sowohl auf die Anfangs- als auch auf die Zielgröße zugreifen,
Animation. SizeTransform
legt auch fest, ob der Inhalt zugeschnitten werden soll.
an die Komponentengröße anpassen.
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() } } }
Ein- und Ausblenden von Kindern animieren
Genau wie AnimatedVisibility
wird die animateEnterExit
ist im Content-Lambda von AnimatedContent
verfügbar. Verwenden
EnterAnimation
und ExitAnimation
auf die direkten oder indirekten
für Kinder separat ansehen.
Benutzerdefinierte Animation hinzufügen
Genau wie bei AnimatedVisibility
ist das Feld transition
im
Lambda von AnimatedContent
. Hiermit können Sie eine benutzerdefinierte Animation erstellen.
Effekt, der gleichzeitig mit dem AnimatedContent
-Übergang ausgeführt wird. Weitere Informationen finden Sie unter
updateTransition.
Mit Crossfade
zwischen zwei Layouts animieren
Crossfade
animiert zwischen zwei Layouts mit einer Überblendungsanimation. Durch Umschalten
Wert, der an den Parameter current
übergeben wird, wird der Inhalt durch eine
überblendende Animation.
var currentPage by remember { mutableStateOf("A") } Crossfade(targetState = currentPage) { screen -> when (screen) { "A" -> Text("Page A") "B" -> Text("Page B") } }
Integrierte Animationsmodifikatoren
Zusammensetzbare Größenänderungen mit animateContentSize
animieren
<ph type="x-smartling-placeholder">
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 zu Listenelementen
Wenn Sie die Neuanordnung von Elementen innerhalb einer Lazy-Liste oder eines Lazy-Rasters animieren möchten, sehen Sie sich die Dokumentation zur Animation von Lazy-Layoutelementen
Empfehlungen für dich
- Hinweis: Der Linktext wird angezeigt, wenn JavaScript deaktiviert ist.
- Wertbezogene Animationen
- Animationen in „Compose“
- Unterstützung für Animationstools {:#tooling}