animateFloat
@Composable
public fun InfiniteTransition.animateFloat(
initialValue: Float,
targetValue: Float,
animationSpec: InfiniteRepeatableSpec<Float>,
label: String = "FloatAnimation",
): State<Float>
Creates an animation of Float type that runs infinitely as a part of the given
InfiniteTransition
.
Once the animation is created, it will run from initialValue
to targetValue
and repeat.
Depending on the RepeatMode
of the provided animationSpec
, the animation could either restart
after each iteration (i.e. RepeatMode.Restart
), or reverse after each iteration (i.e .
RepeatMode.Reverse
).
If initialValue
or targetValue
is changed at any point during the animation, the animation
will be restarted with the new initialValue
and targetValue
. Note: this means continuity
will not be preserved.
A label
for differentiating this animation from others in android studio.
Deprecated animateFloat APIs now have a new label parameter added.
@Composable
public fun InfiniteTransition.animateFloat(
initialValue: Float,
targetValue: Float,
animationSpec: InfiniteRepeatableSpec<Float>,
): State<Float>
@Composable
public inline fun <S> Transition<S>.animateFloat(
noinline transitionSpec: @Composable Transition.Segment<S>.() -> FiniteAnimationSpec<Float> = {
spring()
},
label: String = "FloatAnimation",
targetValueByState: @Composable (state: S) -> Float,
): State<Float>
Creates a Float animation as a part of the given Transition
. This means the states of this
animation will be managed by the Transition
.
targetValueByState
is used as a mapping from a target state to the target value of this
animation. Transition
will be using this mapping to determine what value to target this
animation towards. Note that targetValueByState
is a composable function. This means the
mapping function could access states, CompositionLocals, themes, etc. If the targetValue changes
outside of a Transition
run (i.e. when the Transition
already reached its targetState), the
Transition
will start running again to ensure this animation reaches its new target smoothly.
An optional transitionSpec
can be provided to specify (potentially different) animation for
each pair of initialState and targetState. FiniteAnimationSpec
includes any non-infinite
animation, such as tween
, spring
, keyframes
and even repeatable
, but not
infiniteRepeatable
. By default, transitionSpec
uses a spring
animation for all transition
destinations.
label
is used to differentiate from other animations in the same transition in Android Studio.
Returns
A State object, the value of which is updated by animation |
Code Examples
AnimateFloatSample
@Composable
fun AnimateFloatSample() {
// enum class ButtonStatus {Initial, Pressed, Released}
@Composable
fun AnimateAlphaAndScale(modifier: Modifier, transition: Transition<ButtonStatus>) {
// Defines a float animation as a child animation of transition. This allows the
// transition to manage the states of this animation. The returned State<Float> from the
// [animateFloat] function is used here as a property delegate.
// This float animation will use the default [spring] for all transition destinations, as
// specified by the default `transitionSpec`.
val scale: Float by
transition.animateFloat { state -> if (state == ButtonStatus.Pressed) 1.2f else 1f }
// Alternatively, we can specify different animation specs based on the initial state and
// target state of the a transition run using `transitionSpec`.
val alpha: Float by
transition.animateFloat(
transitionSpec = {
when {
ButtonStatus.Initial isTransitioningTo ButtonStatus.Pressed -> {
keyframes {
durationMillis = 225
0f at 0 // optional
0.3f at 75
0.2f at 225 // optional
}
}
ButtonStatus.Pressed isTransitioningTo ButtonStatus.Released -> {
tween(durationMillis = 220)
}
else -> {
snap()
}
}
}
) { state ->
// Same target value for Initial and Released states
if (state == ButtonStatus.Pressed) 0.2f else 0f
}
Box(modifier.graphicsLayer(alpha = alpha, scaleX = scale)) {
// content goes here
}
}
}
InfiniteTransitionSample
@Composable
fun InfiniteTransitionSample() {
@Composable
fun InfinitelyPulsingHeart() {
// Creates an [InfiniteTransition] instance for managing child animations.
val infiniteTransition = rememberInfiniteTransition()
// Creates a child animation of float type as a part of the [InfiniteTransition].
val scale by
infiniteTransition.animateFloat(
initialValue = 3f,
targetValue = 6f,
animationSpec =
infiniteRepeatable(
// Infinitely repeating a 1000ms tween animation using default easing curve.
animation = tween(1000),
// After each iteration of the animation (i.e. every 1000ms), the animation
// will
// start again from the [initialValue] defined above.
// This is the default [RepeatMode]. See [RepeatMode.Reverse] below for an
// alternative.
repeatMode = RepeatMode.Restart,
),
)
// Creates a Color animation as a part of the [InfiniteTransition].
val color by
infiniteTransition.animateColor(
initialValue = Color.Red,
targetValue = Color(0xff800000), // Dark Red
animationSpec =
infiniteRepeatable(
// Linearly interpolate between initialValue and targetValue every 1000ms.
animation = tween(1000, easing = LinearEasing),
// Once [TargetValue] is reached, starts the next iteration in reverse (i.e.
// from
// TargetValue to InitialValue). Then again from InitialValue to
// TargetValue. This
// [RepeatMode] ensures that the animation value is *always continuous*.
repeatMode = RepeatMode.Reverse,
),
)
Box(Modifier.fillMaxSize()) {
Icon(
Icons.Filled.Favorite,
contentDescription = null,
modifier =
Modifier.align(Alignment.Center).graphicsLayer(scaleX = scale, scaleY = scale),
tint = color,
)
}
}
}