InfiniteTransition


InfiniteTransition is responsible for running child animations. Child animations can be added using InfiniteTransition.animateColor, InfiniteTransition.animateFloat, or InfiniteTransition.animateValue. Child animations will start running as soon as they enter the composition, and will not stop until they are removed from the composition.

import androidx.compose.animation.animateColor
import androidx.compose.animation.core.LinearEasing
import androidx.compose.animation.core.RepeatMode
import androidx.compose.animation.core.animateFloat
import androidx.compose.animation.core.infiniteRepeatable
import androidx.compose.animation.core.rememberInfiniteTransition
import androidx.compose.animation.core.tween
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material.Icon
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Favorite
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.graphicsLayer

@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
        )
    }
}

Summary

Public properties

List<InfiniteTransition.TransitionAnimationState<*, *>>

List of TransitionAnimationStates that are in a InfiniteTransition.

Cmn
String

A label for differentiating this animation from others in android studio.

Cmn

Extension functions

State<Float>
@Composable
InfiniteTransition.animateFloat(
    initialValue: Float,
    targetValue: Float,
    animationSpec: InfiniteRepeatableSpec<Float>,
    label: String
)

Creates an animation of Float type that runs infinitely as a part of the given InfiniteTransition.

Cmn
State<T>
@Composable
<T : Any?, V : AnimationVector> InfiniteTransition.animateValue(
    initialValue: T,
    targetValue: T,
    typeConverter: TwoWayConverter<T, V>,
    animationSpec: InfiniteRepeatableSpec<T>,
    label: String
)

Creates an animation of type T that runs infinitely as a part of the given InfiniteTransition.

Cmn
State<Color>
@Composable
InfiniteTransition.animateColor(
    initialValue: Color,
    targetValue: Color,
    animationSpec: InfiniteRepeatableSpec<Color>,
    label: String
)

Creates a Color animation that runs infinitely as a part of the given InfiniteTransition.

Cmn

Public properties

animations

val animationsList<InfiniteTransition.TransitionAnimationState<*, *>>

List of TransitionAnimationStates that are in a InfiniteTransition.

label

val labelString

A label for differentiating this animation from others in android studio.

Extension functions

@Composable
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.

import androidx.compose.animation.animateColor
import androidx.compose.animation.core.LinearEasing
import androidx.compose.animation.core.RepeatMode
import androidx.compose.animation.core.animateFloat
import androidx.compose.animation.core.infiniteRepeatable
import androidx.compose.animation.core.rememberInfiniteTransition
import androidx.compose.animation.core.tween
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material.Icon
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Favorite
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.graphicsLayer

@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
        )
    }
}
@Composable
fun <T : Any?, V : AnimationVector> InfiniteTransition.animateValue(
    initialValue: T,
    targetValue: T,
    typeConverter: TwoWayConverter<T, V>,
    animationSpec: InfiniteRepeatableSpec<T>,
    label: String = "ValueAnimation"
): State<T>

Creates an animation of type T that runs infinitely as a part of the given InfiniteTransition. Any data type can be animated so long as it can be converted from and to an AnimationVector. This conversion needs to be provided as a typeConverter. Some examples of such TwoWayConverter are: Int.VectorConverter, Dp.VectorConverter, Size.VectorConverter, etc

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.

import androidx.compose.animation.core.FastOutLinearInEasing
import androidx.compose.animation.core.RepeatMode
import androidx.compose.animation.core.VectorConverter
import androidx.compose.animation.core.animateValue
import androidx.compose.animation.core.infiniteRepeatable
import androidx.compose.animation.core.keyframes
import androidx.compose.animation.core.rememberInfiniteTransition
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.offset
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp

// Creates an [InfiniteTransition] instance to run child animations.
val infiniteTransition = rememberInfiniteTransition()
// Infinitely animate a Dp offset from 0.dp to 100.dp
val offsetX by
    infiniteTransition.animateValue(
        initialValue = 0.dp,
        targetValue = 100.dp,
        typeConverter = Dp.VectorConverter,
        animationSpec =
            infiniteRepeatable(
                animation =
                    keyframes {
                        durationMillis = 500
                        0.dp at 200 // ms
                        80.dp at 300 using FastOutLinearInEasing
                    }
                // Use the default RepeatMode.Restart to start from 0.dp after each iteration
            )
    )

Box(Modifier.offset(x = offsetX)) {
    // Content goes here
}
@Composable
fun InfiniteTransition.animateColor(
    initialValue: Color,
    targetValue: Color,
    animationSpec: InfiniteRepeatableSpec<Color>,
    label: String = "ColorAnimation"
): State<Color>

Creates a Color animation 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 initial/targetValue. Note: this means animation continuity will not be preserved when changing either initialValue or targetValue.

A label for differentiating this animation from others in android studio.

import androidx.compose.animation.animateColor
import androidx.compose.animation.core.LinearEasing
import androidx.compose.animation.core.RepeatMode
import androidx.compose.animation.core.Transition
import androidx.compose.animation.core.animateFloat
import androidx.compose.animation.core.infiniteRepeatable
import androidx.compose.animation.core.rememberInfiniteTransition
import androidx.compose.animation.core.tween
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material.Icon
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Favorite
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.graphicsLayer

@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
        )
    }
}