Creates an animation of Float type that runs infinitely as a part of the given [InfiniteTransition].
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,
)
}
}
}