AnimationState


AnimationState contains the necessary information to indicate the state of an animation. Once an AnimationState is constructed, it can only be updated/mutated by animations. If there's a need to mutate some of the fields of an AnimationState, consider using copy functions.

Summary

Public constructors

<T : Any?, V : AnimationVector> AnimationState(
    typeConverter: TwoWayConverter<T, V>,
    initialValue: T,
    initialVelocityVector: V?,
    lastFrameTimeNanos: Long,
    finishedTimeNanos: Long,
    isRunning: Boolean
)
Cmn

Public functions

open String
Cmn

Public properties

Long

The time when the animation finished successfully in the System.nanoTime timebase.

Cmn
Boolean

Indicates whether the animation is currently running.

Cmn
Long

Last frame time of the animation.

Cmn
TwoWayConverter<T, V>

TwoWayConverter to convert type T from and to AnimationVector

Cmn
open T

Current value of the AnimationState.

Cmn
T

Velocity of type T, converted from velocityVector.

Cmn
V

Current velocity vector of the AnimationState.

Cmn

Extension functions

AnimationState<FloatAnimationVector1D>
AnimationState<FloatAnimationVector1D>.copy(
    value: Float,
    velocity: Float,
    lastFrameTimeNanos: Long,
    finishedTimeNanos: Long,
    isRunning: Boolean
)

Creates a new AnimationState of Float value type from a given AnimationState of the same type.

Cmn
AnimationState<T, V>
<T : Any?, V : AnimationVector> AnimationState<T, V>.copy(
    value: T,
    velocityVector: V?,
    lastFrameTimeNanos: Long,
    finishedTimeNanos: Long,
    isRunning: Boolean
)

Creates a new AnimationState from a given AnimationState.

Cmn
suspend Unit
<T : Any?, V : AnimationVector> AnimationState<T, V>.animateDecay(
    animationSpec: DecayAnimationSpec<T>,
    sequentialAnimation: Boolean,
    block: AnimationScope<T, V>.() -> Unit
)

Decay animation that slows down from the current velocity and value captured in AnimationState until the velocity reaches 0.

Cmn
suspend Unit
<T : Any?, V : AnimationVector> AnimationState<T, V>.animateTo(
    targetValue: T,
    animationSpec: AnimationSpec<T>,
    sequentialAnimation: Boolean,
    block: AnimationScope<T, V>.() -> Unit
)

Target based animation that takes the value and velocity from the AnimationState as the starting condition, and animate to the targetValue, using the animationSpec.

Cmn

Extension properties

Boolean

Indicates whether the given AnimationState is for an animation that has finished, indicated by AnimationState.finishedTimeNanos having a specified value.

Cmn

Public constructors

AnimationState

<T : Any?, V : AnimationVector> AnimationState(
    typeConverter: TwoWayConverter<T, V>,
    initialValue: T,
    initialVelocityVector: V? = null,
    lastFrameTimeNanos: Long = AnimationConstants.UnspecifiedTime,
    finishedTimeNanos: Long = AnimationConstants.UnspecifiedTime,
    isRunning: Boolean = false
)
Parameters
typeConverter: TwoWayConverter<T, V>

TwoWayConverter to convert type T from and to AnimationVector

initialValue: T

initial value of the AnimationState

initialVelocityVector: V? = null

initial velocity of the AnimationState, null (i.e. no velocity) by default.

lastFrameTimeNanos: Long = AnimationConstants.UnspecifiedTime

last frame time of the animation, AnimationConstants.UnspecifiedTime by default

finishedTimeNanos: Long = AnimationConstants.UnspecifiedTime

the time that the animation finished successfully, AnimationConstants.UnspecifiedTime until then

isRunning: Boolean = false

whether the AnimationState is currently being updated by an animation. False by default

Public functions

toString

open fun toString(): String

Public properties

finishedTimeNanos

val finishedTimeNanosLong

The time when the animation finished successfully in the System.nanoTime timebase.

If the animation has never finished (i.e. currently running, interrupted, or never started), this will be AnimationConstants.UnspecifiedTime, unless specified otherwise in AnimationState constructor.

isRunning

val isRunningBoolean

Indicates whether the animation is currently running.

lastFrameTimeNanos

val lastFrameTimeNanosLong

Last frame time of the animation.

If the animation has never started, this will be AnimationConstants.UnspecifiedTime, unless specified otherwise in the AnimationState constructor. lastFrameTimeNanos is the frame time when the animation is last updated, in the System.nanoTime timebase. It is also used for starting a sequential animation in AnimationState.animateTo. This allows the sequential animation to set its start time to when the previous animation is interrupted or finished.

typeConverter

val typeConverterTwoWayConverter<T, V>

TwoWayConverter to convert type T from and to AnimationVector

value

open val value: T

Current value of the AnimationState.

velocity

val velocity: T

Velocity of type T, converted from velocityVector.

velocityVector

val velocityVector: V

Current velocity vector of the AnimationState.

Extension functions

fun AnimationState<FloatAnimationVector1D>.copy(
    value: Float = this.value,
    velocity: Float = this.velocityVector.value,
    lastFrameTimeNanos: Long = this.lastFrameTimeNanos,
    finishedTimeNanos: Long = this.finishedTimeNanos,
    isRunning: Boolean = this.isRunning
): AnimationState<FloatAnimationVector1D>

Creates a new AnimationState of Float value type from a given AnimationState of the same type. This function allows some of the fields to be different in the new AnimationState.

Parameters
value: Float = this.value

value of the AnimationState, using the value of the given AnimationState by default

velocity: Float = this.velocityVector.value

velocity of the AnimationState, using the velocity of the given AnimationState by default.

lastFrameTimeNanos: Long = this.lastFrameTimeNanos

last frame time of the animation, same as the given AnimationState by default

finishedTimeNanos: Long = this.finishedTimeNanos

the time that the animation finished successfully, same as the given AnimationState by default.

isRunning: Boolean = this.isRunning

whether the AnimationState is currently being updated by an animation. Same as the given AnimationState by default

Returns
AnimationState<FloatAnimationVector1D>

A new AnimationState instance copied from the given instance, with some fields optionally altered

fun <T : Any?, V : AnimationVector> AnimationState<T, V>.copy(
    value: T = this.value,
    velocityVector: V? = this.velocityVector.copy(),
    lastFrameTimeNanos: Long = this.lastFrameTimeNanos,
    finishedTimeNanos: Long = this.finishedTimeNanos,
    isRunning: Boolean = this.isRunning
): AnimationState<T, V>

Creates a new AnimationState from a given AnimationState. This function allows some of the fields to be different in the new AnimationState.

Parameters
value: T = this.value

value of the AnimationState, using the value of the given AnimationState by default

velocityVector: V? = this.velocityVector.copy()

velocity of the AnimationState, using the velocity of the given AnimationState by default.

lastFrameTimeNanos: Long = this.lastFrameTimeNanos

last frame time of the animation, same as the given AnimationState by default

finishedTimeNanos: Long = this.finishedTimeNanos

the time that the animation finished successfully, AnimationConstants.UnspecifiedTime until then. Default value is the same as the given AnimationState.

isRunning: Boolean = this.isRunning

whether the AnimationState is currently being updated by an animation. Same as the given AnimationState by default

Returns
AnimationState<T, V>

A new AnimationState instance copied from the given instance, with some fields optionally altered

suspend fun <T : Any?, V : AnimationVector> AnimationState<T, V>.animateDecay(
    animationSpec: DecayAnimationSpec<T>,
    sequentialAnimation: Boolean = false,
    block: AnimationScope<T, V>.() -> Unit = {}
): Unit

Decay animation that slows down from the current velocity and value captured in AnimationState until the velocity reaches 0. During the animation, the given AnimationState will be updated with the up-to-date value/velocity, frame time, etc. This is often used to animate the result of a fling gesture.

Parameters
animationSpec: DecayAnimationSpec<T>

Defines the decay animation that will be used for this animation. Some options for animationSpec include: splineBasedDecay and exponentialDecay.

sequentialAnimation: Boolean = false

Indicates whether the animation should use the AnimationState.lastFrameTimeNanos as the starting time (if true), or start in a new frame. By default, sequentialAnimation is false, to start the animation in a few frame. In cases where an on-going animation is interrupted and a new animation is started to carry over the momentum, using the interruption time (captured in AnimationState.lastFrameTimeNanos) creates a smoother animation.

block: AnimationScope<T, V>.() -> Unit = {}

will be invoked on every frame during the animation, and the AnimationScope will be checked against cancellation before the animation continues. To cancel the animation from the block, simply call AnimationScope.cancelAnimation. After AnimationScope.cancelAnimation is called, block will not be invoked again. The animation loop will exit after the block returns. All the animation related info can be accessed via AnimationScope.

suspend fun <T : Any?, V : AnimationVector> AnimationState<T, V>.animateTo(
    targetValue: T,
    animationSpec: AnimationSpec<T> = spring(),
    sequentialAnimation: Boolean = false,
    block: AnimationScope<T, V>.() -> Unit = {}
): Unit

Target based animation that takes the value and velocity from the AnimationState as the starting condition, and animate to the targetValue, using the animationSpec. During the animation, the given AnimationState will be updated with the up-to-date value/velocity, frame time, etc.

import androidx.compose.animation.core.AnimationState
import androidx.compose.animation.core.Spring
import androidx.compose.animation.core.animate
import androidx.compose.animation.core.animateTo
import androidx.compose.animation.core.isFinished
import androidx.compose.animation.core.spring
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.remember

@Composable
fun simpleAnimate(
    target: Float,
): Float {
    // Create an AnimationState to be updated by the animation.
    val animationState = remember { AnimationState(target) }

    // Launch the suspend animation into the composition's CoroutineContext, and pass
    // `target` to LaunchedEffect so that when`target` changes the old animation job is
    // canceled, and a new animation is created with a new target.
    LaunchedEffect(target) {
        // This starts an animation that updates the animationState on each frame
        animationState.animateTo(
            targetValue = target,
            // Use a low stiffness spring. This can be replaced with any type of `AnimationSpec`
            animationSpec = spring(stiffness = Spring.StiffnessLow),
            // If the previous animation was interrupted (i.e. not finished), configure the
            // animation as a sequential animation to continue from the time the animation was
            // interrupted.
            sequentialAnimation = !animationState.isFinished
        )
        // When the function above returns, the animation has finished.
    }
    // Return the value updated by the animation.
    return animationState.value
}
Parameters
targetValue: T

The target value that the animation will animate to.

animationSpec: AnimationSpec<T> = spring()

The animation configuration that will be used. spring by default.

sequentialAnimation: Boolean = false

Indicates whether the animation should use the AnimationState.lastFrameTimeNanos as the starting time (if true), or start in a new frame. By default, sequentialAnimation is false, to start the animation in a few frame. In cases where an on-going animation is interrupted and a new animation is started to carry over the momentum, using the interruption time (captured in AnimationState.lastFrameTimeNanos) creates a smoother animation.

block: AnimationScope<T, V>.() -> Unit = {}

Will be invoked on every frame, and the AnimationScope will be checked against cancellation before the animation continues. To cancel the animation from the block, simply call AnimationScope.cancelAnimation. After AnimationScope.cancelAnimation is called, block will not be invoked again. The animation loop will exit after the block returns. All the animation related info can be accessed via AnimationScope.

Extension properties

isFinished

val AnimationState<*, *>.isFinishedBoolean

Indicates whether the given AnimationState is for an animation that has finished, indicated by AnimationState.finishedTimeNanos having a specified value.