Viele der Animations-APIs akzeptieren in der Regel Parameter zum Anpassen ihres Verhaltens.
Animationen mit dem Parameter AnimationSpec anpassen
Bei den meisten Animations-APIs können Entwickler Animationsspezifikationen mit einem optionalen AnimationSpec-Parameter anpassen.
val alpha: Float by animateFloatAsState( targetValue = if (enabled) 1f else 0.5f, // Configure the animation duration and easing. animationSpec = tween(durationMillis = 300, easing = FastOutSlowInEasing), label = "alpha" )
Es gibt verschiedene Arten von AnimationSpec, mit denen sich unterschiedliche Arten von Animationen erstellen lassen.
Physikbasierte Animationen mit spring erstellen
Mit spring wird eine physikbasierte Animation zwischen Start- und Endwerten erstellt. Sie verwendet zwei Parameter: dampingRatio und stiffness.
dampingRatio definiert, wie stark die Feder schwingen soll. Der Standardwert ist Spring.DampingRatioNoBouncy.
stiffness definiert, wie schnell sich die Feder dem Endwert nähern soll. Der Standardwert ist Spring.StiffnessMedium.
val value by animateFloatAsState( targetValue = 1f, animationSpec = spring( dampingRatio = Spring.DampingRatioHighBouncy, stiffness = Spring.StiffnessMedium ), label = "spring spec" )
spring kann Unterbrechungen besser verarbeiten als dauerbasierte AnimationSpec-Typen, da die Kontinuität der Geschwindigkeit garantiert wird, wenn sich der Zielwert während der Animationen ändert. spring wird von vielen Animations-APIs wie animate*AsState und updateTransition als Standard-AnimationSpec verwendet.
Wenn wir beispielsweise eine spring-Konfiguration auf die folgende Animation anwenden, die durch Berührung des Nutzers ausgelöst wird, und die Animation unterbrechen, während sie läuft, sehen Sie, dass die Reaktion bei Verwendung von tween nicht so flüssig ist wie bei Verwendung von spring.
tween- im Vergleich zu spring-Spezifikationen für Animationen und Unterbrechung von AnimationenAnimation zwischen Start- und Endwerten mit einer Easing-Kurve mit tween
tween animiert zwischen Start- und Endwerten über die angegebene durationMillis mithilfe einer Easing-Kurve. tween ist eine Abkürzung für das Wort „zwischen“, da es zwischen zwei Werten steht.
Sie können auch delayMillis angeben, um den Beginn der Animation zu verzögern.
val value by animateFloatAsState( targetValue = 1f, animationSpec = tween( durationMillis = 300, delayMillis = 50, easing = LinearOutSlowInEasing ), label = "tween delay" )
Weitere Informationen finden Sie unter Easing.
Mit keyframes können Sie Animationen für bestimmte Werte zu bestimmten Zeitpunkten erstellen.
keyframes wird basierend auf den Snapshot-Werten animiert, die zu verschiedenen Zeitstempeln während der Animation angegeben werden. Zu jedem Zeitpunkt wird der Animationswert zwischen zwei Keyframe-Werten interpoliert. Für jeden dieser Keyframes kann ein Easing-Wert angegeben werden, um die Interpolationskurve festzulegen.
Es ist optional, die Werte bei 0 ms und bei der Dauer anzugeben. Wenn Sie diese Werte nicht angeben, werden standardmäßig die Start- und Endwerte der Animation verwendet.
val value by animateFloatAsState( targetValue = 1f, animationSpec = keyframes { durationMillis = 375 0.0f at 0 using LinearOutSlowInEasing // for 0-15 ms 0.2f at 15 using FastOutLinearInEasing // for 15-75 ms 0.4f at 75 // ms 0.4f at 225 // ms }, label = "keyframe" )
Mit keyframesWithSplines können Sie Animationen zwischen Keyframes flüssig gestalten.
Wenn Sie eine Animation erstellen möchten, die beim Übergang zwischen Werten einer glatten Kurve folgt, können Sie keyframesWithSplines anstelle von keyframes-Animationsspezifikationen verwenden.
val offset by animateOffsetAsState( targetValue = Offset(300f, 300f), animationSpec = keyframesWithSpline { durationMillis = 6000 Offset(0f, 0f) at 0 Offset(150f, 200f) atFraction 0.5f Offset(0f, 100f) atFraction 0.7f } )
Spline-basierte Keyframes sind besonders nützlich für die 2D-Bewegung von Elementen auf dem Bildschirm.
In den folgenden Videos werden die Unterschiede zwischen keyframes und keyframesWithSpline anhand derselben Menge von x- und y-Koordinaten veranschaulicht, denen ein Kreis folgen soll.
keyframes
|
keyframesWithSplines
|
|---|---|
Wie Sie sehen, bieten splinebasierte Keyframes weichere Übergänge zwischen Punkten, da sie Bezierkurven verwenden, um Elemente flüssig zu animieren. Diese Spezifikation ist für eine voreingestellte Animation nützlich. Wenn Sie jedoch mit benutzerdefinierten Punkten arbeiten, ist es besser, Federn zu verwenden, um eine ähnliche Glätte zwischen den Punkten zu erzielen, da diese unterbrechbar sind.
Animation mit repeatable wiederholen
repeatable führt eine zeitbasierte Animation (z. B. tween oder keyframes) wiederholt aus, bis die angegebene Anzahl von Wiederholungen erreicht ist. Mit dem Parameter repeatMode können Sie angeben, ob die Animation wiederholt werden soll, indem sie von Anfang (RepeatMode.Restart) oder vom Ende (RepeatMode.Reverse) beginnt.
val value by animateFloatAsState( targetValue = 1f, animationSpec = repeatable( iterations = 3, animation = tween(durationMillis = 300), repeatMode = RepeatMode.Reverse ), label = "repeatable spec" )
Animation mit infiniteRepeatable unendlich oft wiederholen
infiniteRepeatable ist wie repeatable, wird aber unendlich oft wiederholt.
val value by animateFloatAsState( targetValue = 1f, animationSpec = infiniteRepeatable( animation = tween(durationMillis = 300), repeatMode = RepeatMode.Reverse ), label = "infinite repeatable" )
Bei Tests mit ComposeTestRule werden Animationen mit infiniteRepeatable nicht ausgeführt. Die Komponente wird mit dem Anfangswert jedes animierten Werts gerendert.
Sofort zum Endwert springen mit snap
snap ist ein spezieller AnimationSpec, der den Wert sofort auf den Endwert ändert. Sie können delayMillis angeben, um den Beginn der Animation zu verzögern.
val value by animateFloatAsState( targetValue = 1f, animationSpec = snap(delayMillis = 50), label = "snap spec" )
Benutzerdefinierte Easing-Funktion festlegen
Dauerbasierte AnimationSpec-Vorgänge (z. B. tween oder keyframes) verwenden Easing, um den Bruchteil einer Animation anzupassen. So kann der animierte Wert beschleunigen und verlangsamen, anstatt sich mit einer konstanten Geschwindigkeit zu bewegen. „Fraction“ ist ein Wert zwischen 0 (Anfang) und 1,0 (Ende), der den aktuellen Punkt in der Animation angibt.
Easing ist eine Funktion, die einen Bruchwert zwischen 0 und 1,0 akzeptiert und einen Gleitkommawert zurückgibt. Der zurückgegebene Wert kann außerhalb der Grenze liegen, um eine Überschreitung oder Unterschreitung darzustellen. Ein benutzerdefiniertes Easing kann wie im folgenden Code erstellt werden.
val CustomEasing = Easing { fraction -> fraction * fraction } @Composable fun EasingUsage() { val value by animateFloatAsState( targetValue = 1f, animationSpec = tween( durationMillis = 300, easing = CustomEasing ), label = "custom easing" ) // …… }
Compose bietet mehrere integrierte Easing-Funktionen, die die meisten Anwendungsfälle abdecken.
Weitere Informationen dazu, welche Easing-Funktion Sie je nach Szenario verwenden sollten, finden Sie unter Speed – Material Design.
FastOutSlowInEasingLinearOutSlowInEasingFastOutLinearEasingLinearEasingCubicBezierEasing- Mehr anzeigen
Benutzerdefinierte Datentypen animieren, indem sie in AnimationVector konvertiert werden und umgekehrt
Die meisten Compose-Animations-APIs unterstützen standardmäßig Float, Color, Dp und andere grundlegende Datentypen als Animationswerte. Manchmal müssen Sie jedoch andere Datentypen animieren, einschließlich Ihrer benutzerdefinierten. Während der Animation wird jeder animierte Wert als AnimationVector dargestellt. Der Wert wird durch ein entsprechendes TwoWayConverter in ein AnimationVector und umgekehrt konvertiert, sodass das Core Animation-System sie einheitlich verarbeiten kann. Ein Int wird beispielsweise als AnimationVector1D dargestellt, das einen einzelnen Gleitkommawert enthält.
TwoWayConverter für Int sieht so aus:
val IntToVector: TwoWayConverter<Int, AnimationVector1D> = TwoWayConverter({ AnimationVector1D(it.toFloat()) }, { it.value.toInt() })
Color ist im Grunde ein Satz aus 4 Werten: Rot, Grün, Blau und Alpha. Daher wird Color in ein AnimationVector4D umgewandelt, das 4 Gleitkommawerte enthält. Auf diese Weise wird jeder in Animationen verwendete Datentyp je nach Dimensionalität in AnimationVector1D, AnimationVector2D, AnimationVector3D oder AnimationVector4D konvertiert. So können verschiedene Komponenten des Objekts unabhängig voneinander animiert werden, jeweils mit eigener Geschwindigkeitsmessung. Auf integrierte Konverter für einfache Datentypen kann über Konverter wie Color.VectorConverter oder Dp.VectorConverter zugegriffen werden.
Wenn Sie Unterstützung für einen neuen Datentyp als animierenden Wert hinzufügen möchten, können Sie ein eigenes TwoWayConverter erstellen und der API zur Verfügung stellen. Mit animateValueAsState können Sie beispielsweise Ihren benutzerdefinierten Datentyp so animieren:
data class MySize(val width: Dp, val height: Dp) @Composable fun MyAnimation(targetSize: MySize) { val animSize: MySize by animateValueAsState( targetSize, TwoWayConverter( convertToVector = { size: MySize -> // Extract a float value from each of the `Dp` fields. AnimationVector2D(size.width.value, size.height.value) }, convertFromVector = { vector: AnimationVector2D -> MySize(vector.v1.dp, vector.v2.dp) } ), label = "size" ) }
Die folgende Liste enthält einige integrierte VectorConverters:
Color.VectorConverterDp.VectorConverterOffset.VectorConverterInt.VectorConverterFloat.VectorConverterIntSize.VectorConverter
Empfehlungen für dich
- Hinweis: Linktext wird angezeigt, wenn JavaScript deaktiviert ist.
- Wertbezogene Animationen
- Iterative Codeentwicklung {:#iterative-code-dev }
- Animationen in Compose