Viele der Animation APIs akzeptieren häufig Parameter zum Anpassen ihres Verhaltens.
Animationen mit dem Parameter AnimationSpec anpassen
Bei den meisten Animation APIs können Entwickler Animationsspezifikationen mit einem optionalen Parameter AnimationSpec 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 zum Erstellen verschiedener Arten von Animationen.
Physikbasierte Animation mit spring erstellen
spring erstellt eine physikbasierte Animation zwischen Start- und Endwerten. Dazu werden zwei Parameter verwendet: dampingRatio und stiffness.
dampingRatio definiert, wie stark die Feder schwingen soll. Der Standardwert ist Spring.DampingRatioNoBouncy.
stiffness definiert, wie schnell sich die Feder auf den Endwert zubewegen 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 reibungsloser verarbeiten als zeitbasierte AnimationSpec-Typen, da die Kontinuität der Geschwindigkeit garantiert wird, wenn sich der Zielwert während der Animation ändert. spring wird von vielen Animation APIs als Standard-AnimationSpec verwendet, z. B. von animate*AsState und updateTransition.
Wenn wir beispielsweise eine spring-Konfiguration auf die folgende Animation anwenden, die durch eine Nutzerberührung ausgelöst wird, können Sie sehen, dass die Reaktion bei einer Unterbrechung der Animation mit tween nicht so reibungslos ist wie mit spring.
tween- und spring-Spezifikationen für die Animation festlegen und die Animation unterbrechen.Mit tween zwischen Start- und Endwerten animieren
tween animiert zwischen Start- und Endwerten über die angegebene durationMillis mit einer Easing-Kurve. tween ist eine Abkürzung für „between“ (zwischen), da die Animation zwischen zwei Werten verläuft.
Sie können auch delayMillis angeben, um den Start 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 zu bestimmten Zeiten bestimmte Werte animieren
keyframes animiert basierend auf den Snapshot-Werten, die zu verschiedenen Zeitstempeln während der Animation angegeben wurden. Zu jedem Zeitpunkt wird der Animationswert zwischen zwei Keyframe-Werten interpoliert. Für jedes dieser Keyframes kann Easing angegeben werden, um die Interpolationskurve zu bestimmen.
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 reibungslos zwischen Keyframes animieren
Wenn Sie eine Animation erstellen möchten, die beim Übergang zwischen
Werten einer reibungslosen Kurve folgt, können Sie anstelle von keyframes die Animation
specs keyframesWithSplines 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 Spline-basierte Keyframes reibungslosere Übergänge zwischen Punkten, da sie Bézierkurven verwenden, um reibungslos zwischen Elementen zu animieren. Diese Spezifikation ist nützlich für eine voreingestellte Animation. Wenn Sie jedoch mit nutzergesteuerten Punkten arbeiten, ist es besser, Federn zu verwenden, um eine ähnliche Reibungslosigkeit 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. Sie können den Parameter repeatMode übergeben, um anzugeben, ob die Animation wiederholt werden soll, indem sie von Anfang an (RepeatMode.Restart) oder vom Ende aus (RepeatMode.Reverse) gestartet wird.
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 funktioniert 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" )
In Tests mit
ComposeTestRule,
werden Animationen mit infiniteRepeatable nicht ausgeführt. Die Komponente wird mit dem Anfangswert jedes animierten Werts gerendert.
Mit snap sofort zum Endwert springen
snap ist eine spezielle AnimationSpec, die den Wert sofort auf den Endwert ändert. Sie können delayMillis angeben, um den Start der Animation zu verzögern.
val value by animateFloatAsState( targetValue = 1f, animationSpec = snap(delayMillis = 50), label = "snap spec" )
Benutzerdefinierte Easing-Funktion festlegen
Zeitbasierte AnimationSpec-Vorgänge (z. B. tween oder keyframes) verwenden Easing, um den Anteil einer Animation anzupassen. Dadurch kann der animierte Wert beschleunigt und verlangsamt werden, anstatt sich mit einer konstanten Geschwindigkeit zu bewegen. Der Anteil ist ein Wert zwischen 0 (Start) und 1,0 (Ende), der den aktuellen Punkt in der Animation angibt.
Easing ist eine Funktion, die einen Anteilswert zwischen 0 und 1,0 verwendet und einen Gleitkommawert zurückgibt. Der zurückgegebene Wert kann außerhalb der Grenze liegen, um ein Überschwingen oder Unterschwingen darzustellen. Eine benutzerdefinierte Easing-Funktion 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 zur Verwendung von Easing je nach Szenario finden Sie unter Geschwindigkeit – Material Design.
FastOutSlowInEasingLinearOutSlowInEasingFastOutLinearEasingLinearEasingCubicBezierEasing- Mehr anzeigen
Benutzerdefinierte Datentypen animieren, indem sie in AnimationVector konvertiert werden
Die meisten Compose Animation 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 Datentypen. Während der Animation wird jeder animierte Wert als AnimationVector dargestellt. Der Wert wird mit einem entsprechenden TwoWayConverter in einen AnimationVector und umgekehrt konvertiert, sodass das Kernanimationssystem sie einheitlich verarbeiten kann. Ein Int wird beispielsweise als AnimationVector1D dargestellt, der 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 Wesentlichen eine Menge von vier Werten: Rot, Grün, Blau und Alpha. Daher wird Color in einen AnimationVector4D konvertiert, der vier Gleitkommawerte enthält. Auf diese Weise wird jeder in Animationen verwendete Datentyp je nach Dimensionalität in AnimationVector1D, AnimationVector2D, AnimationVector3D oder AnimationVector4D konvertiert. Dadurch können verschiedene Komponenten des Objekts unabhängig voneinander animiert werden, jeweils mit eigener Geschwindigkeitsverfolgung. Auf integrierte Konverter für grundlegende Datentypen kann mit Konvertern wie Color.VectorConverter oder Dp.VectorConverter zugegriffen werden.
Wenn Sie Unterstützung für einen neuen Datentyp als Animationswert hinzufügen möchten, können Sie einen eigenen 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 VectorConverter:
Color.VectorConverterDp.VectorConverterOffset.VectorConverterInt.VectorConverterFloat.VectorConverterIntSize.VectorConverter
Empfehlungen für Sie
- Hinweis: Linktext wird angezeigt, wenn JavaScript deaktiviert ist
- Wertbasierte Animationen
- Iterative Codeentwicklung {:#iterative-code-dev }
- Animationen in Compose