Many of the Animation APIs commonly accept parameters for customizing their behavior.
Customize animations with the AnimationSpec
parameter
Most animation APIs allow developers to customize animation specifications by an
optional AnimationSpec
parameter.
val alpha: Float by animateFloatAsState( targetValue = if (enabled) 1f else 0.5f, // Configure the animation duration and easing. animationSpec = tween(durationMillis = 300, easing = FastOutSlowInEasing) )
There are different kinds of AnimationSpec
for creating different types of
animation.
Create physics-based animation with spring
spring
creates a physics-based animation between start and end values. It
takes 2 parameters: dampingRatio
and stiffness
.
dampingRatio
defines how bouncy the spring should be. The default value is
Spring.DampingRatioNoBouncy
.
stiffness
defines how fast the spring should move toward the end value. The
default value is Spring.StiffnessMedium
.
val value by animateFloatAsState( targetValue = 1f, animationSpec = spring( dampingRatio = Spring.DampingRatioHighBouncy, stiffness = Spring.StiffnessMedium ) )
spring
can handle interruptions more smoothly than duration-based
AnimationSpec
types because it guarantees the continuity of velocity when
target value changes amid animations. spring
is used as the default
AnimationSpec by many animation APIs, such as animate*AsState
and
updateTransition
.
Animate between start and end values with easing curve with tween
tween
animates between start and end values over the specified
durationMillis
using an easing curve. See Easing for more
information. You can also specify delayMillis
to postpone the start of the
animation.
val value by animateFloatAsState( targetValue = 1f, animationSpec = tween( durationMillis = 300, delayMillis = 50, easing = LinearOutSlowInEasing ) )
Animate to specific values at certain timings with keyframes
keyframes
animates based on the snapshot values specified at different
timestamps in the duration of the animation. At any given time, the animation
value will be interpolated between two keyframe values. For each of these
keyframes, Easing can be specified to determine the interpolation curve.
It is optional to specify the values at 0 ms and at the duration time. If you do not specify these values, they default to the start and end values of the animation, respectively.
val value by animateFloatAsState( targetValue = 1f, animationSpec = keyframes { durationMillis = 375 0.0f at 0 with LinearOutSlowInEasing // for 0-15 ms 0.2f at 15 with FastOutLinearInEasing // for 15-75 ms 0.4f at 75 // ms 0.4f at 225 // ms } )
Repeat an animation with repeatable
repeatable
runs a duration-based animation (such as tween
or keyframes
)
repeatedly until it reaches the specified iteration count. You can pass the
repeatMode
parameter to specify whether the animation should repeat by
starting from the beginning (RepeatMode.Restart
) or from the end
(RepeatMode.Reverse
).
val value by animateFloatAsState( targetValue = 1f, animationSpec = repeatable( iterations = 3, animation = tween(durationMillis = 300), repeatMode = RepeatMode.Reverse ) )
Repeat an animation infinitely with infiniteRepeatable
infiniteRepeatable
is like repeatable
, but it repeats for an infinite amount
of iterations.
val value by animateFloatAsState( targetValue = 1f, animationSpec = infiniteRepeatable( animation = tween(durationMillis = 300), repeatMode = RepeatMode.Reverse ) )
In tests using
ComposeTestRule
,
animations using infiniteRepeatable
are not run. The component will be
rendered using the initial value of each animated value.
Immediately snap to end value with snap
snap
is a special AnimationSpec
that immediately switches the value to the
end value. You can specify delayMillis
in order to delay the start of the
animation.
val value by animateFloatAsState( targetValue = 1f, animationSpec = snap(delayMillis = 50) )
Set a custom easing function
Duration-based AnimationSpec
operations (such as tween
or keyframes
) use
Easing
to adjust an animation's fraction. This allows the animating value to
speed up and slow down, rather than moving at a constant rate. Fraction is a
value between 0 (start) and 1.0 (end) indicating the current point in the
animation.
Easing is in fact a function that takes a fraction value between 0 and 1.0 and returns a float. The returned value can be outside the boundary to represent overshoot or undershoot. A custom Easing can be created like the code below.
val CustomEasing = Easing { fraction -> fraction * fraction } @Composable fun EasingUsage() { val value by animateFloatAsState( targetValue = 1f, animationSpec = tween( durationMillis = 300, easing = CustomEasing ) ) // …… }
Compose provides several built-in Easing
functions that cover most use cases.
See Speed - Material
Design for more
information about what Easing to use depending on your scenario.
FastOutSlowInEasing
LinearOutSlowInEasing
FastOutLinearEasing
LinearEasing
CubicBezierEasing
- See more
Animate custom data types by converting to and from AnimationVector
Most Compose animation APIs support Float
, Color
, Dp
, and other basic data
types as animation values out of the box, but you sometimes need to animate
other data types including your custom ones. During animation, any animating
value is represented as an AnimationVector
. The value is converted into an
AnimationVector
and vice versa by a corresponding TwoWayConverter
so that
the core animation system can handle them uniformly. For example, an Int
is
represented as an AnimationVector1D
that holds a single float value.
TwoWayConverter
for Int
looks like this:
val IntToVector: TwoWayConverter<Int, AnimationVector1D> = TwoWayConverter({ AnimationVector1D(it.toFloat()) }, { it.value.toInt() })
Color
is essentially a set of 4 values, red, green, blue, and alpha, so
Color
is converted into an AnimationVector4D
that holds 4 float values. In
this manner, every data type used in animations is converted to either
AnimationVector1D
, AnimationVector2D
, AnimationVector3D
, or
AnimationVector4D
depending on its dimensionality. This allows different
components of the object to be animated independently, each with their own
velocity tracking. Built-in converters for basic data types can be accessed
using Color.VectorConverter
, Dp.VectorConverter
, and so on.
When you want to add support for a new data type as an animating value, you can
create your own TwoWayConverter
and provide it to the API. For example, you
can use animateValueAsState
to animate your custom data type like this:
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) } ) ) }
The following list includes some built-in VectorConverter
s:
Color.VectorConverter
Dp.VectorConverter
Offset.VectorConverter
Int.VectorConverter
Float.VectorConverter
IntSize.VectorConverter
Recommended for you
- Note: link text is displayed when JavaScript is off
- Value-based animations
- Iterative code development {:#iterative-code-dev }
- Animations in Compose