Compose verfügt über viele integrierte Animationsmechanismen und es kann schwierig sein, entscheiden Sie sich für eins. Nachfolgend finden Sie eine Liste mit gängigen Anwendungsfällen für Animationen. Für ausführlichere Informationen zu den verschiedenen verfügbaren API-Optionen finden Sie in der Dokumentation zum Erstellen von Animationen.
Gängige zusammensetzbare Eigenschaften animieren
Compose bietet praktische APIs, mit denen Sie viele gängige Animationsanwendungen. In diesem Abschnitt wird gezeigt, wie Sie gängige einer zusammensetzbaren Funktion.
Animieren eines Erscheinens / Verschwindens
<ph type="x-smartling-placeholder">![Grüne zusammensetzbare Funktion, die sich ein- und ausblenden lässt](https://developer.android.com/static/develop/ui/compose/images/animations/animated_visibility_column.gif?authuser=6&hl=de)
Verwenden Sie AnimatedVisibility
, um eine zusammensetzbare Funktion ein- oder auszublenden. Kinder drinnen
AnimatedVisibility
kann Modifier.animateEnterExit()
für die eigene Eingabe verwenden
oder den Übergang zu beenden.
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 // ... }
Mit den Eingabe- und Exit-Parametern von AnimatedVisibility
können Sie konfigurieren, wie
verhält sich eine zusammensetzbare Funktion,
wenn sie erscheint und wieder verschwindet. Lesen Sie den vollständigen
in der Dokumentation.
Sie können die Sichtbarkeit
einer zusammensetzbaren Funktion auch animieren,
Alpha im Zeitverlauf mit animateFloatAsState
:
var visible by remember { mutableStateOf(true) } val animatedAlpha by animateFloatAsState( targetValue = if (visible) 1.0f else 0f, label = "alpha" ) Box( modifier = Modifier .size(200.dp) .graphicsLayer { alpha = animatedAlpha } .clip(RoundedCornerShape(8.dp)) .background(colorGreen) .align(Alignment.TopCenter) ) { }
Die Änderung des Alpha-Werts bedeutet jedoch, dass die zusammensetzbare Funktion weiterhin
in der Komposition und nimmt weiterhin den Platz ein, in dem es sich befindet. Dieses
dazu führen, dass Screenreader und andere Bedienungshilfen
das Element auf dem Bildschirm. AnimatedVisibility
entfernt hingegen
das Element aus der Komposition.
![Alpha einer zusammensetzbaren Funktion animieren](https://developer.android.com/static/develop/ui/compose/images/animations/animated_visibility_alpha.gif?authuser=6&hl=de)
Hintergrundfarbe animieren
<ph type="x-smartling-placeholder">![Zusammensetzbar, wobei sich die Hintergrundfarbe als Animation im Laufe der Zeit ändert, bei der die Farben übergangen werden](https://developer.android.com/static/develop/ui/compose/images/animations/animated_forever.gif?authuser=6&hl=de)
val animatedColor by animateColorAsState( if (animateBackgroundColor) colorGreen else colorBlue, label = "color" ) Column( modifier = Modifier.drawBehind { drawRect(animatedColor) } ) { // your composable here }
Diese Option ist leistungsfähiger als die Verwendung von Modifier.background()
.
Modifier.background()
ist für eine Farbeinstellung in Einzelaufnahme akzeptabel, aber wenn
Animieren einer Farbe über einen bestimmten Zeitraum, kann dies zu mehr Neuzusammensetzungen
notwendig ist.
Informationen zur unendlichen Animierung der Hintergrundfarbe finden Sie unter Animation wiederholen .
Größe einer zusammensetzbaren Funktion animieren
<ph type="x-smartling-placeholder">![Grüne zusammensetzbare Funktion, deren Größe animiert wird, ändert sich reibungslos.](https://developer.android.com/static/develop/ui/compose/images/animations/animated_content_size.gif?authuser=6&hl=de)
Mit „Compose“ können Sie die Größe von zusammensetzbaren Funktionen auf verschiedene Arten animieren. Verwenden Sie
animateContentSize()
für Animationen zwischen zusammensetzbaren Größenänderungen
Wenn Sie beispielsweise ein Textfeld haben, das Text enthält, der sich von einem zu
Mehrere Linien können Sie Modifier.animateContentSize()
verwenden, um eine gleichmäßigere
Übergang:
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 } ) { }
Sie können auch AnimatedContent
mit einem SizeTransform
verwenden, um
wie Größenänderungen erfolgen sollen.
Position der zusammensetzbaren Funktion animieren
<ph type="x-smartling-placeholder">![Grüne, zusammensetzbare Funktion mit sanfter Animation nach unten und rechts](https://developer.android.com/static/develop/ui/compose/images/animations/animated_offset.gif?authuser=6&hl=de)
Um die Position einer zusammensetzbaren Funktion zu animieren, verwenden Sie Modifier.offset{ }
in Kombination mit
animateIntOffsetAsState()
.
var moved by remember { mutableStateOf(false) } val pxToMove = with(LocalDensity.current) { 100.dp.toPx().roundToInt() } val offset by animateIntOffsetAsState( targetValue = if (moved) { IntOffset(pxToMove, pxToMove) } else { IntOffset.Zero }, label = "offset" ) Box( modifier = Modifier .offset { offset } .background(colorBlue) .size(100.dp) .clickable( interactionSource = remember { MutableInteractionSource() }, indication = null ) { moved = !moved } )
Wenn Sie sicherstellen möchten, dass zusammensetzbare Funktionen nicht über oder unter anderen
zusammensetzbare Funktionen verwenden, wenn Sie für die Animation von Position oder Größe Modifier.layout{ }
verwenden. Dieses
gibt Änderungen der Größe und Position an das übergeordnete Element weiter, was sich auf
Kinder.
Wenn Sie z. B. ein Box
innerhalb einer Column
und die anderen untergeordneten Elemente verschieben,
verschieben müssen, wenn Box
bewegt wird, fügen Sie die Versatzinformationen mit
Modifier.layout{ }
so:
var toggled by remember { mutableStateOf(false) } val interactionSource = remember { MutableInteractionSource() } Column( modifier = Modifier .padding(16.dp) .fillMaxSize() .clickable(indication = null, interactionSource = interactionSource) { toggled = !toggled } ) { val offsetTarget = if (toggled) { IntOffset(150, 150) } else { IntOffset.Zero } val offset = animateIntOffsetAsState( targetValue = offsetTarget, label = "offset" ) Box( modifier = Modifier .size(100.dp) .background(colorBlue) ) Box( modifier = Modifier .layout { measurable, constraints -> val offsetValue = if (isLookingAhead) offsetTarget else offset.value val placeable = measurable.measure(constraints) layout(placeable.width + offsetValue.x, placeable.height + offsetValue.y) { placeable.placeRelative(offsetValue) } } .size(100.dp) .background(colorGreen) ) Box( modifier = Modifier .size(100.dp) .background(colorBlue) ) }<ph type="x-smartling-placeholder">
![Zwei Boxen,wobei die zweite Box ihre X- und Y-Position animiert. Die dritte Box reagiert, indem sie sich ebenfalls um den Y-Wert bewegt.](https://developer.android.com/static/develop/ui/compose/images/animations/animated_layout_modifier.gif?authuser=6&hl=de)
Modifier.layout{ }
Padding einer zusammensetzbaren Funktion animieren
<ph type="x-smartling-placeholder">![Die grüne zusammensetzbare Funktion wird durch einen Klick kleiner und größer und die Abstände sind animiert.](https://developer.android.com/static/develop/ui/compose/images/animations/animated_padding.gif?authuser=6&hl=de)
Um den Abstand einer zusammensetzbaren Funktion zu animieren, verwenden Sie animateDpAsState
in Kombination mit
Modifier.padding()
:
var toggled by remember { mutableStateOf(false) } val animatedPadding by animateDpAsState( if (toggled) { 0.dp } else { 20.dp }, label = "padding" ) Box( modifier = Modifier .aspectRatio(1f) .fillMaxSize() .padding(animatedPadding) .background(Color(0xff53D9A1)) .clickable( interactionSource = remember { MutableInteractionSource() }, indication = null ) { toggled = !toggled } )
Höhe einer zusammensetzbaren Funktion animieren
Um die Höhe einer zusammensetzbaren Funktion zu animieren, verwenden Sie animateDpAsState
in Kombination mit
Modifier.graphicsLayer{ }
. Für einmalige Höhenänderungen verwenden Sie
Modifier.shadow()
Wenn Sie den Schatten animieren, verwenden Sie
Der Modifier.graphicsLayer{ }
-Modifikator ist die leistungsstärkere Option.
val mutableInteractionSource = remember { MutableInteractionSource() } val pressed = mutableInteractionSource.collectIsPressedAsState() val elevation = animateDpAsState( targetValue = if (pressed.value) { 32.dp } else { 8.dp }, label = "elevation" ) Box( modifier = Modifier .size(100.dp) .align(Alignment.Center) .graphicsLayer { this.shadowElevation = elevation.value.toPx() } .clickable(interactionSource = mutableInteractionSource, indication = null) { } .background(colorGreen) ) { }
Alternativ können Sie die zusammensetzbare Funktion Card
verwenden und die Höheneigenschaft auf
für die einzelnen Bundesstaaten.
Textskalierung, -übersetzung oder -drehung animieren
<ph type="x-smartling-placeholder">![Zusammensetzbarer Text mit Text](https://developer.android.com/static/develop/ui/compose/images/animations/animated_text.gif?authuser=6&hl=de)
Legen Sie beim Animieren der Skalierung, Verschiebung oder Drehung von Text den textMotion
fest.
auf TextStyle
auf TextMotion.Animated
gesetzt. So sorgen Sie für eine
Textanimationen zu wechseln. Verwenden Sie Modifier.graphicsLayer{ }
für Folgendes:
übersetzen, drehen oder skalieren.
val infiniteTransition = rememberInfiniteTransition(label = "infinite transition") val scale by infiniteTransition.animateFloat( initialValue = 1f, targetValue = 8f, animationSpec = infiniteRepeatable(tween(1000), RepeatMode.Reverse), label = "scale" ) Box(modifier = Modifier.fillMaxSize()) { Text( text = "Hello", modifier = Modifier .graphicsLayer { scaleX = scale scaleY = scale transformOrigin = TransformOrigin.Center } .align(Alignment.Center), // Text composable does not take TextMotion as a parameter. // Provide it via style argument but make sure that we are copying from current theme style = LocalTextStyle.current.copy(textMotion = TextMotion.Animated) ) }
Textfarbe animieren
<ph type="x-smartling-placeholder">![Der Text](https://developer.android.com/static/develop/ui/compose/images/animations/animated_text_color.gif?authuser=6&hl=de)
Um die Textfarbe zu animieren, verwende die Lambda-Funktion color
in der zusammensetzbaren Funktion BasicText
:
val infiniteTransition = rememberInfiniteTransition(label = "infinite transition") val animatedColor by infiniteTransition.animateColor( initialValue = Color(0xFF60DDAD), targetValue = Color(0xFF4285F4), animationSpec = infiniteRepeatable(tween(1000), RepeatMode.Reverse), label = "color" ) BasicText( text = "Hello Compose", color = { animatedColor }, // ... )
Zwischen verschiedenen Inhaltstypen wechseln
<ph type="x-smartling-placeholder">![Greenscreen mit Text](https://developer.android.com/static/develop/ui/compose/images/animations/animated_content_slower.gif?authuser=6&hl=de)
Verwenden Sie AnimatedContent
für Animationen zwischen verschiedenen zusammensetzbaren Funktionen,
Standardfade zwischen zusammensetzbaren Funktionen verwenden möchten, verwenden Sie Crossfade
.
var state by remember { mutableStateOf(UiState.Loading) } AnimatedContent( state, transitionSpec = { fadeIn( animationSpec = tween(3000) ) togetherWith fadeOut(animationSpec = tween(3000)) }, modifier = Modifier.clickable( interactionSource = remember { MutableInteractionSource() }, indication = null ) { state = when (state) { UiState.Loading -> UiState.Loaded UiState.Loaded -> UiState.Error UiState.Error -> UiState.Loading } }, label = "Animated Content" ) { targetState -> when (targetState) { UiState.Loading -> { LoadingScreen() } UiState.Loaded -> { LoadedScreen() } UiState.Error -> { ErrorScreen() } } }
AnimatedContent
kann so angepasst werden, dass viele unterschiedliche Arten von Eingaben und
Exit-Übergänge. Weitere Informationen finden Sie in der Dokumentation zu
AnimatedContent
oder lesen Sie diesen Blogpost auf
AnimatedContent
Animiere zu verschiedenen Zielen
<ph type="x-smartling-placeholder">![Zwei zusammensetzbare Elemente, eine mit der Aufschrift „Landing“ und eine blaue „Detail“](https://developer.android.com/static/develop/ui/compose/images/animations/navigation_compose_animation.gif?authuser=6&hl=de)
Um Übergänge zwischen zusammensetzbaren Funktionen zu animieren, wenn Sie die
navigation-compose verwenden, geben Sie enterTransition
und
exitTransition
für eine zusammensetzbare Funktion. Sie können die Standardanimation auch
wird für alle Ziele auf der obersten Ebene NavHost
verwendet:
val navController = rememberNavController() NavHost( navController = navController, startDestination = "landing", enterTransition = { EnterTransition.None }, exitTransition = { ExitTransition.None } ) { composable("landing") { ScreenLanding( // ... ) } composable( "detail/{photoUrl}", arguments = listOf(navArgument("photoUrl") { type = NavType.StringType }), enterTransition = { fadeIn( animationSpec = tween( 300, easing = LinearEasing ) ) + slideIntoContainer( animationSpec = tween(300, easing = EaseIn), towards = AnimatedContentTransitionScope.SlideDirection.Start ) }, exitTransition = { fadeOut( animationSpec = tween( 300, easing = LinearEasing ) ) + slideOutOfContainer( animationSpec = tween(300, easing = EaseOut), towards = AnimatedContentTransitionScope.SlideDirection.End ) } ) { backStackEntry -> ScreenDetails( // ... ) } }
Es gibt viele verschiedene Arten von Wechsel zwischen Ein- und Ausblenden. unterschiedliche Auswirkungen auf eingehende und ausgehende Inhalte haben, siehe Dokumentation.
Animation wiederholen
<ph type="x-smartling-placeholder">![Ein grüner Hintergrund, der sich durch Animieren der beiden Farben in einen blauen Hintergrund verwandelt.](https://developer.android.com/static/develop/ui/compose/images/animations/animated_forever.gif?authuser=6&hl=de)
rememberInfiniteTransition
mit einem infiniteRepeatable
verwenden
animationSpec
, um die Animation fortlaufend zu wiederholen. RepeatModes
ändern zu
wie er hin und her wechseln soll.
Mit finiteRepeatable
können Sie eine bestimmte Anzahl von Wiederholungen festlegen.
val infiniteTransition = rememberInfiniteTransition(label = "infinite") val color by infiniteTransition.animateColor( initialValue = Color.Green, targetValue = Color.Blue, animationSpec = infiniteRepeatable( animation = tween(1000, easing = LinearEasing), repeatMode = RepeatMode.Reverse ), label = "color" ) Column( modifier = Modifier.drawBehind { drawRect(color) } ) { // your composable here }
Animation beim Start einer zusammensetzbaren Funktion starten
LaunchedEffect
wird ausgeführt, wenn eine zusammensetzbare Funktion in die Zusammensetzung aufgenommen wird. Los gehts
eine Animation beim Start einer zusammensetzbaren Funktion.
Statusänderung. Animatable
mit der Methode animateTo
zum Starten von
Animation beim Start:
val alphaAnimation = remember { Animatable(0f) } LaunchedEffect(Unit) { alphaAnimation.animateTo(1f) } Box( modifier = Modifier.graphicsLayer { alpha = alphaAnimation.value } )
Sequenzielle Animationen erstellen
<ph type="x-smartling-placeholder">![Vier Kreise mit grünen Pfeilen, die nacheinander animiert werden](https://developer.android.com/static/develop/ui/compose/images/animations/multiple_properties_sequential.gif?authuser=6&hl=de)
Verwenden Sie die Animatable
-Koroutinen-APIs für sequenzielle oder gleichzeitige Ausführung
Animationen. Aufrufen von animateTo
für Animatable
nach den anderen Ursachen
jede Animation wird erst beendet, wenn die vorherigen Animationen beendet sind, bevor Sie fortfahren .
Der Grund hierfür ist, dass es sich um eine Sperren-Funktion handelt.
val alphaAnimation = remember { Animatable(0f) } val yAnimation = remember { Animatable(0f) } LaunchedEffect("animationKey") { alphaAnimation.animateTo(1f) yAnimation.animateTo(100f) yAnimation.animateTo(500f, animationSpec = tween(100)) }
Gleichzeitige Animationen erstellen
<ph type="x-smartling-placeholder">![Drei Kreise mit grünen Pfeilen, die jeweils als Animation dienen und alle gleichzeitig animieren](https://developer.android.com/static/develop/ui/compose/images/animations/multiple_properties.gif?authuser=6&hl=de)
Verwenden Sie die Koroutine-APIs (Animatable#animateTo()
oder animate
) oder
die Transition
API verwenden, um gleichzeitige Animationen zu erstellen. Wenn Sie mehrere
Funktionen im Kontext einer Koroutine starten, starten sie die Animationen im gleichen
Zeit:
val alphaAnimation = remember { Animatable(0f) } val yAnimation = remember { Animatable(0f) } LaunchedEffect("animationKey") { launch { alphaAnimation.animateTo(1f) } launch { yAnimation.animateTo(100f) } }
Mit der updateTransition
API können Sie denselben Status für
verschiedene Eigenschaftenanimationen gleichzeitig erstellen. Im Beispiel unten wird eine Animation
Zwei Eigenschaften, die durch eine Statusänderung gesteuert werden, rect
und borderWidth
:
var currentState by remember { mutableStateOf(BoxState.Collapsed) } val transition = updateTransition(currentState, label = "transition") val rect by transition.animateRect(label = "rect") { state -> when (state) { BoxState.Collapsed -> Rect(0f, 0f, 100f, 100f) BoxState.Expanded -> Rect(100f, 100f, 300f, 300f) } } val borderWidth by transition.animateDp(label = "borderWidth") { state -> when (state) { BoxState.Collapsed -> 1.dp BoxState.Expanded -> 0.dp } }
Animationsleistung optimieren
Animationen in „Compose“ können zu Leistungsproblemen führen. Dies liegt an der Natur des Animation: schnelles Verschieben oder Ändern von Pixeln auf dem Bildschirm, Frame für Frame, um die Illusion von Bewegung zu erzeugen.
Sehen Sie sich die verschiedenen Phasen des Schreibens an: Komposition, Layout und Zeichnen. Wenn die Layoutphase verändert, müssen alle betroffenen zusammensetzbaren Layout neu gestalten und neu zeichnen. Wenn Ihre Animation in der Zeichenphase stattfindet, standardmäßig leistungsfähiger sein, als wenn Sie die Animation im Layout ausführen, da es insgesamt weniger Arbeit hätte.
Wähle Lambda aus, damit deine App während der Animation möglichst wenig tut
Version von Modifier
. Dabei wird die Neuzusammensetzung übersprungen und
außerhalb der Kompositionsphase zu erstellen. Andernfalls verwenden Sie
Modifier.graphicsLayer{ }
, da dieser Modifikator immer in der Zeichnung ausgeführt wird
. Weitere Informationen hierzu finden Sie im Abschnitt Lesevorgänge aussetzen in
Leistungsdokumentation.
Timing der Animation ändern
Beim Schreiben werden standardmäßig Frühlingsanimationen verwendet. Federn oder
physikbasierten Animationen
natürlicher wirken. Sie sind auch unterbrechbar,
sie berücksichtigen die aktuelle Geschwindigkeit des Objekts anstelle einer festen Zeit.
Wenn Sie die Standardeinstellung überschreiben möchten, können Sie alle oben gezeigten Animations-APIs
können eine animationSpec
festlegen,
um die Ausführung einer Animation anzupassen,
ob sie über eine bestimmte Dauer
ausgeführt werden oder hüpfender sein soll.
Im Folgenden finden Sie eine Zusammenfassung der verschiedenen animationSpec
-Optionen:
spring
: Physikbasierte Animationen, die Standardeinstellung für alle Animationen. Ich kann das Steifheits- oder Dämpfungsverhältnis ändern, um eine andere Animation zu erzielen. Design.tween
(kurz für zwischen): Animationsdauer nach Dauer, animiert mit der FunktionEasing
zwischen zwei Werten.keyframes
: Spezifikation für die Angabe von Werten an bestimmten wichtigen Punkten in einer Animation.repeatable
: Dauerbasierte Spezifikation, die eine bestimmte Anzahl von Ausführungen hat, durchRepeatMode
angegeben.infiniteRepeatable
: Dauerbasierte Spezifikation, die unbegrenzt gültig ist.snap
: Andockt sofort und ohne Animation an den Endwert.
![Alt-Text hier eingeben](https://developer.android.com/static/develop/ui/compose/images/animations/animated_spec_set.gif?authuser=6&hl=de)
Weitere Informationen zu animationSpecs finden Sie in der vollständigen Dokumentation.
Weitere Informationen
Weitere Beispiele für lustige Animationen in „Schreiben“ finden Sie hier:
- 5 Kurzanimationen in „Schreiben“
- Jellyfish in „Compose“ bewegen
AnimatedContent
in „Schreiben“ anpassen- Easing-Funktionen in Compose