androidx.compose.animation.core

In this page, you'll find documentation for types, properties, and functions available in the androidx.compose.animation.core package. For example:

If you're looking for guidance instead, check out the Animations in Compose guide.

Interfaces

Animation

This interface provides a convenient way to query from an VectorizedAnimationSpec or FloatDecayAnimationSpec: It spares the need to pass the starting conditions and in some cases ending condition for each value or velocity query, and instead only requires the play time to be passed for such queries.

Cmn
AnimationSpec

AnimationSpec stores the specification of an animation, including 1) the data type to be animated, and 2) the animation configuration (i.e. VectorizedAnimationSpec) that will be used once the data (of type T) has been converted to AnimationVector.

Cmn
DecayAnimationSpec

DecayAnimationSpec stores the specification of an animation, including 1) the data type to be animated, and 2) the animation configuration (i.e. VectorizedDecayAnimationSpec) that will be used once the data (of type T) has been converted to AnimationVector.

Cmn
DurationBasedAnimationSpec

This describes AnimationSpecs that are based on a fixed duration, such as KeyframesSpec, TweenSpec, and SnapSpec.

Cmn
Easing

Easing is a way to adjust an animation’s fraction.

Cmn
FiniteAnimationSpec

FiniteAnimationSpec is the interface that all non-infinite AnimationSpecs implement, including: TweenSpec, SpringSpec, KeyframesSpec, RepeatableSpec, SnapSpec, etc.

Cmn
FloatAnimationSpec

FloatAnimationSpec interface is similar to VectorizedAnimationSpec, except it deals exclusively with floats.

Cmn
FloatDecayAnimationSpec

This animation interface is intended to be stateless, just like Animation.

Cmn
Transition.Segment

Segment holds initialState and targetState, which are the beginning and end of a transition.

Cmn
TwoWayConverter

TwoWayConverter class contains the definition on how to convert from an arbitrary type T to a AnimationVector, and convert the AnimationVector back to the type T.

Cmn
VectorizedAnimationSpec

VectorizedAnimationSpecs are stateless vector based animation specifications.

Cmn
VectorizedDecayAnimationSpec

VectorizedDecayAnimationSpecs are stateless vector based decay animation specifications.

Cmn
VectorizedDurationBasedAnimationSpec

Base class for VectorizedAnimationSpecs that are based on a fixed durationMillis.

Cmn
VectorizedFiniteAnimationSpec

All the finite VectorizedAnimationSpecs implement this interface, including: VectorizedKeyframesSpec, VectorizedTweenSpec, VectorizedRepeatableSpec, VectorizedSnapSpec, VectorizedSpringSpec, etc.

Cmn

Classes

Animatable

Animatable is a value holder that automatically animates its value when the value is changed via animateTo.

Cmn
AnimationResult

AnimationResult contains information about an animation at the end of the animation.

Cmn
AnimationScope

AnimationScope provides all the animation related info specific to an animation run.

Cmn
AnimationState

AnimationState contains the necessary information to indicate the state of an animation.

Cmn
AnimationVector

AnimationVector class that is the base class of AnimationVector1D, AnimationVector2D, AnimationVector3D and AnimationVector4D.

Cmn
AnimationVector1D

This class defines a 1D vector.

Cmn
AnimationVector2D

This class defines a 2D vector that contains two Float values for the two dimensions.

Cmn
AnimationVector3D

This class defines a 3D vector that contains three Float value fields for the three dimensions.

Cmn
AnimationVector4D

This class defines a 4D vector that contains four Float fields for its four dimensions.

Cmn
ArcAnimationSpec

DurationBasedAnimationSpec that interpolates 2-dimensional values using arcs of quarter of an Ellipse.

Cmn
ArcMode

Interpolation mode for Arc-based animation spec.

Cmn
CubicBezierEasing

A cubic polynomial easing.

Cmn
DecayAnimation

DecayAnimation is an animation that slows down from initialVelocityVector as time goes on.

Cmn
DeferredTargetAnimation

DeferredTargetAnimation is intended for animations where the target is unknown at the time of instantiation.

Cmn
FloatExponentialDecaySpec

This is a decay animation where the friction/deceleration is always proportional to the velocity.

Cmn
FloatSpringSpec

FloatSpringSpec animation uses a spring animation to animate a Float value.

Cmn
FloatTweenSpec

FloatTweenSpec animates a Float value from any start value to any end value using a provided easing function.

Cmn
InfiniteRepeatableSpec

InfiniteRepeatableSpec repeats the provided animation infinite amount of times.

Cmn
InfiniteTransition

InfiniteTransition is responsible for running child animations.

Cmn
InfiniteTransition.TransitionAnimationState

Each animation created using InfiniteTransition.animateColor, InfiniteTransition.animateFloat, or InfiniteTransition.animateValue is represented as a TransitionAnimationState in InfiniteTransition.

Cmn
KeyframeBaseEntity

Base holder class for building a keyframes animation.

Cmn
KeyframesSpec

KeyframesSpec creates a VectorizedKeyframesSpec animation.

Cmn
KeyframesSpec.KeyframeEntity

Holder class for building a keyframes animation.

Cmn
KeyframesSpec.KeyframesSpecConfig

KeyframesSpecConfig stores a mutable configuration of the key frames, including durationMillis, delayMillis, and all the key frames.

Cmn
KeyframesSpecBaseConfig

Shared configuration class used as DSL for keyframe based animations.

Cmn
KeyframesWithSplineSpec

KeyframesWithSplineSpec creates a keyframe based DurationBasedAnimationSpec using the Monotone cubic Hermite spline to interpolate between the values in config.

Cmn
KeyframesWithSplineSpec.KeyframesWithSplineSpecConfig
Cmn
MutableTransitionState

MutableTransitionState contains two fields: currentState and targetState.

Cmn
PathEasing

An easing function for an arbitrary Path.

Cmn
RepeatableSpec

RepeatableSpec takes another DurationBasedAnimationSpec and plays it iterations times.

Cmn
SeekableTransitionState

A TransitionState that can manipulate the progress of the Transition by seeking with snapTo or animating with animateTo.

Cmn
SnapSpec

SnapSpec describes a jump-cut type of animation.

Cmn
SpringSpec

Creates a SpringSpec that uses the given spring constants (i.e. dampingRatio and stiffness.

Cmn
StartOffset

This class defines a start offset for repeatable and infiniteRepeatable.

Cmn
StartOffsetType

This class defines the two types of StartOffset: StartOffsetType.Delay and StartOffsetType.FastForward.

Cmn
TargetBasedAnimation

This is a convenient animation wrapper class that works for all target based animations, i.e. animations that has a pre-defined end value, unlike decay.

Cmn
Transition

Transition manages all the child animations on a state level.

Cmn
Transition.TransitionAnimationState

Each animation created using animateFloat, animateDp, etc is represented as a TransitionAnimationState in Transition.

Cmn
TransitionState

Use with rememberTransition to create a Transition that can be dynamically targeted with MutableTransitionState or seekable with SeekableTransitionState.

Cmn
TweenSpec

Creates a TweenSpec configured with the given duration, delay, and easing curve.

Cmn
VectorizedFloatAnimationSpec

A convenient implementation of VectorizedFloatAnimationSpec that turns a FloatAnimationSpec into a multi-dimensional VectorizedFloatAnimationSpec, by using the same FloatAnimationSpec on each dimension of the AnimationVector that is being animated.

Cmn
VectorizedInfiniteRepeatableSpec

This animation takes another VectorizedDurationBasedAnimationSpec and plays it infinite times.

Cmn
VectorizedKeyframesSpec

VectorizedKeyframesSpec class manages the animation based on the values defined at different timestamps in the duration of the animation (i.e. different keyframes).

Cmn
VectorizedRepeatableSpec

This animation takes another VectorizedDurationBasedAnimationSpec and plays it iterations times.

Cmn
VectorizedSnapSpec

VectorizedSnapSpec immediately snaps the animating value to the end value.

Cmn
VectorizedSpringSpec

VectorizedSpringSpec uses spring animations to animate (each dimension of) AnimationVectors.

Cmn
VectorizedTweenSpec

VectorizedTweenSpec animates a AnimationVector value by interpolating the start and end value, in the given durationMillis using the given easing curve.

Cmn

Objects

AnimationConstants
Cmn
ArcMode.Companion
Cmn
ArcMode.Companion.ArcAbove

Interpolates using a quarter of an Ellipse where the curve is "above" the center of the Ellipse.

Cmn
ArcMode.Companion.ArcBelow

Interpolates using a quarter of an Ellipse where the curve is "below" the center of the Ellipse.

Cmn
ArcMode.Companion.ArcLinear

An ArcMode that forces linear interpolation.

Cmn
Spring

Physics class contains a number of recommended configurations for physics animations.

Cmn

Annotations

Enums

AnimationEndReason

Possible reasons for Animatables to end.

Cmn
RepeatMode

Repeat mode for RepeatableSpec and VectorizedRepeatableSpec.

Cmn

Top-level functions summary

Animatable<FloatAnimationVector1D>
Animatable(initialValue: Float, visibilityThreshold: Float)

This Animatable function creates a float value holder that automatically animates its value when the value is changed via animateTo.

Cmn
AnimationState<FloatAnimationVector1D>
AnimationState(
    initialValue: Float,
    initialVelocity: Float,
    lastFrameTimeNanos: Long,
    finishedTimeNanos: Long,
    isRunning: Boolean
)

Factory method for creating an AnimationState for Float initialValue.

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

Factory method for creating an AnimationState with an initialValue and an initialVelocity.

Cmn
AnimationVector1D

Factory method to create an AnimationVector1D

Cmn
AnimationVector2D

Factory method to create an AnimationVector2D

Cmn
AnimationVector3D
AnimationVector(v1: Float, v2: Float, v3: Float)

Factory method to create an AnimationVector3D

Cmn
AnimationVector4D
AnimationVector(v1: Float, v2: Float, v3: Float, v4: Float)

Factory method to create an AnimationVector4D

Cmn
DecayAnimation<FloatAnimationVector1D>
DecayAnimation(
    animationSpec: FloatDecayAnimationSpec,
    initialValue: Float,
    initialVelocity: Float
)

DecayAnimation is an animation that slows down from initialVelocity as time goes on.

Cmn
TargetBasedAnimation<T, V>
<T : Any?, V : AnimationVector> TargetBasedAnimation(
    animationSpec: AnimationSpec<T>,
    typeConverter: TwoWayConverter<T, V>,
    initialValue: T,
    targetValue: T,
    initialVelocity: T
)

Creates a TargetBasedAnimation with the given start/end conditions of the animation, and the provided animationSpec.

Cmn
TwoWayConverter<T, V>
<T : Any?, V : AnimationVector> TwoWayConverter(
    convertToVector: (T) -> V,
    convertFromVector: (V) -> T
)

Factory method to create a TwoWayConverter that converts a type T from and to an AnimationVector type.

Cmn
suspend Unit
animate(
    initialValue: Float,
    targetValue: Float,
    initialVelocity: Float,
    animationSpec: AnimationSpec<Float>,
    block: (value: Float, velocity: Float) -> Unit
)

Target based animation that animates from the given initialValue towards the targetValue, with an optional initialVelocity.

Cmn
suspend Unit
<T : Any?, V : AnimationVector> animate(
    typeConverter: TwoWayConverter<T, V>,
    initialValue: T,
    targetValue: T,
    initialVelocity: T?,
    animationSpec: AnimationSpec<T>,
    block: (value, velocity) -> Unit
)

Target based animation for animating any data type T, so long as T can be converted to an AnimationVector using typeConverter.

Cmn
suspend Unit
animateDecay(
    initialValue: Float,
    initialVelocity: Float,
    animationSpec: FloatDecayAnimationSpec,
    block: (value: Float, velocity: Float) -> Unit
)

Decay animation that slows down from the given initialVelocity starting at initialValue until the velocity reaches 0.

Cmn
State<Dp>
@Composable
animateDpAsState(
    targetValue: Dp,
    animationSpec: AnimationSpec<Dp>,
    label: String,
    finishedListener: ((Dp) -> Unit)?
)

Fire-and-forget animation function for Dp.

Cmn
State<Float>
@Composable
animateFloatAsState(
    targetValue: Float,
    animationSpec: AnimationSpec<Float>,
    visibilityThreshold: Float,
    label: String,
    finishedListener: ((Float) -> Unit)?
)

Fire-and-forget animation function for Float.

Cmn
State<Int>
@Composable
animateIntAsState(
    targetValue: Int,
    animationSpec: AnimationSpec<Int>,
    label: String,
    finishedListener: ((Int) -> Unit)?
)

Fire-and-forget animation function for Int.

Cmn
State<IntOffset>
@Composable
animateIntOffsetAsState(
    targetValue: IntOffset,
    animationSpec: AnimationSpec<IntOffset>,
    label: String,
    finishedListener: ((IntOffset) -> Unit)?
)

Fire-and-forget animation function for IntOffset.

Cmn
State<IntSize>
@Composable
animateIntSizeAsState(
    targetValue: IntSize,
    animationSpec: AnimationSpec<IntSize>,
    label: String,
    finishedListener: ((IntSize) -> Unit)?
)

Fire-and-forget animation function for IntSize.

Cmn
State<Offset>
@Composable
animateOffsetAsState(
    targetValue: Offset,
    animationSpec: AnimationSpec<Offset>,
    label: String,
    finishedListener: ((Offset) -> Unit)?
)

Fire-and-forget animation function for Offset.

Cmn
State<Rect>
@Composable
animateRectAsState(
    targetValue: Rect,
    animationSpec: AnimationSpec<Rect>,
    label: String,
    finishedListener: ((Rect) -> Unit)?
)

Fire-and-forget animation function for Rect.

Cmn
State<Size>
@Composable
animateSizeAsState(
    targetValue: Size,
    animationSpec: AnimationSpec<Size>,
    label: String,
    finishedListener: ((Size) -> Unit)?
)

Fire-and-forget animation function for Size.

Cmn
State<T>
@Composable
<T : Any?, V : AnimationVector> animateValueAsState(
    targetValue: T,
    typeConverter: TwoWayConverter<T, V>,
    animationSpec: AnimationSpec<T>,
    visibilityThreshold: T?,
    label: String,
    finishedListener: ((T) -> Unit)?
)

Fire-and-forget animation function for any value.

Cmn
DecayAnimationSpec<T>
<T : Any?> exponentialDecay(
    frictionMultiplier: @FloatRange(from = 0.0, fromInclusive = false) Float,
    absVelocityThreshold: @FloatRange(from = 0.0, fromInclusive = false) Float
)

Creates a decay animation spec where the friction/deceleration is always proportional to the velocity.

Cmn
InfiniteRepeatableSpec<T>
<T : Any?> infiniteRepeatable(
    animation: DurationBasedAnimationSpec<T>,
    repeatMode: RepeatMode,
    initialStartOffset: StartOffset
)

Creates a InfiniteRepeatableSpec that plays a DurationBasedAnimationSpec (e.g. TweenSpec, KeyframesSpec) infinite amount of iterations.

Cmn
KeyframesSpec<T>

Creates a KeyframesSpec animation, initialized with init.

Cmn
KeyframesWithSplineSpec<T>

Creates a KeyframesWithSplineSpec animation, initialized with init.

Cmn
InfiniteTransition

Creates a InfiniteTransition that runs infinite child animations.

Cmn
Transition<T>
@Composable
<T : Any?> rememberTransition(
    transitionState: TransitionState<T>,
    label: String?
)

Creates a Transition and puts it in the currentState of the provided transitionState.

Cmn
RepeatableSpec<T>
<T : Any?> repeatable(
    iterations: Int,
    animation: DurationBasedAnimationSpec<T>,
    repeatMode: RepeatMode,
    initialStartOffset: StartOffset
)

Creates a RepeatableSpec that plays a DurationBasedAnimationSpec (e.g. TweenSpec, KeyframesSpec) the amount of iterations specified by iterations.

Cmn
SnapSpec<T>
<T : Any?> snap(delayMillis: Int)

Creates a Snap animation for immediately switching the animating value to the end value.

Cmn
SpringSpec<T>
<T : Any?> spring(dampingRatio: Float, stiffness: Float, visibilityThreshold: T?)

Creates a SpringSpec that uses the given spring constants (i.e. dampingRatio and stiffness.

Cmn
TweenSpec<T>
<T : Any?> tween(durationMillis: Int, delayMillis: Int, easing: Easing)

Creates a TweenSpec configured with the given duration, delay and easing curve.

Cmn
Transition<T>
@Composable
<T : Any?> updateTransition(targetState: T, label: String?)

This sets up a Transition, and updates it with the target provided by targetState.

Cmn
Transition<T>
@Composable
<T : Any?> updateTransition(
    transitionState: MutableTransitionState<T>,
    label: String?
)

This function is deprecated. Use rememberTransition() instead

Cmn
suspend inline R
<R : Any?> withInfiniteAnimationFrameMillis(
    crossinline onFrame: (frameTimeMillis: Long) -> R
)

Like withFrameMillis, but applies the InfiniteAnimationPolicy from the calling CoroutineContext if there is one.

Cmn
suspend R
<R : Any?> withInfiniteAnimationFrameNanos(
    onFrame: (frameTimeNanos: Long) -> R
)

Like withFrameNanos, but applies the InfiniteAnimationPolicy from the calling CoroutineContext if there is one.

Cmn

Extension functions summary

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
inline State<Dp>
@Composable
<S : Any?> Transition<S>.animateDp(
    noinline transitionSpec: @Composable Transition.Segment<S>.() -> FiniteAnimationSpec<Dp>,
    label: String,
    targetValueByState: @Composable (state) -> Dp
)

Creates a Dp animation as a part of the given Transition.

Cmn
inline State<Float>
@Composable
<S : Any?> Transition<S>.animateFloat(
    noinline transitionSpec: @Composable Transition.Segment<S>.() -> FiniteAnimationSpec<Float>,
    label: String,
    targetValueByState: @Composable (state) -> Float
)

Creates a Float animation as a part of the given Transition.

Cmn
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
inline State<Int>
@Composable
<S : Any?> Transition<S>.animateInt(
    noinline transitionSpec: @Composable Transition.Segment<S>.() -> FiniteAnimationSpec<Int>,
    label: String,
    targetValueByState: @Composable (state) -> Int
)

Creates a Int animation as a part of the given Transition.

Cmn
inline State<IntOffset>
@Composable
<S : Any?> Transition<S>.animateIntOffset(
    noinline transitionSpec: @Composable Transition.Segment<S>.() -> FiniteAnimationSpec<IntOffset>,
    label: String,
    targetValueByState: @Composable (state) -> IntOffset
)

Creates a IntOffset animation as a part of the given Transition.

Cmn
inline State<IntSize>
@Composable
<S : Any?> Transition<S>.animateIntSize(
    noinline transitionSpec: @Composable Transition.Segment<S>.() -> FiniteAnimationSpec<IntSize>,
    label: String,
    targetValueByState: @Composable (state) -> IntSize
)

Creates a IntSize animation as a part of the given Transition.

Cmn
inline State<Offset>
@Composable
<S : Any?> Transition<S>.animateOffset(
    noinline transitionSpec: @Composable Transition.Segment<S>.() -> FiniteAnimationSpec<Offset>,
    label: String,
    targetValueByState: @Composable (state) -> Offset
)

Creates an Offset animation as a part of the given Transition.

Cmn
inline State<Rect>
@Composable
<S : Any?> Transition<S>.animateRect(
    noinline transitionSpec: @Composable Transition.Segment<S>.() -> FiniteAnimationSpec<Rect>,
    label: String,
    targetValueByState: @Composable (state) -> Rect
)

Creates a Rect animation as a part of the given Transition.

Cmn
inline State<Size>
@Composable
<S : Any?> Transition<S>.animateSize(
    noinline transitionSpec: @Composable Transition.Segment<S>.() -> FiniteAnimationSpec<Size>,
    label: String,
    targetValueByState: @Composable (state) -> Size
)

Creates a Size animation as a part of the given Transition.

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
inline State<T>
@Composable
<S : Any?, T : Any?, V : AnimationVector> Transition<S>.animateValue(
    typeConverter: TwoWayConverter<T, V>,
    noinline transitionSpec: @Composable Transition.Segment<S>.() -> FiniteAnimationSpec<T>,
    label: String,
    targetValueByState: @Composable (state) -> T
)

Creates an animation of type T as a part of the given Transition.

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
Float
DecayAnimationSpec<Float>.calculateTargetValue(
    initialValue: Float,
    initialVelocity: Float
)

Calculates the target value of a Float decay animation based on the initialValue and initialVelocity.

Cmn
T
<T : Any?, V : AnimationVector> DecayAnimationSpec<T>.calculateTargetValue(
    typeConverter: TwoWayConverter<T, V>,
    initialValue: T,
    initialVelocity: T
)

Calculates the target value of a decay animation based on the initialValue and initialVelocity, and the typeConverter that converts the given type T to AnimationVector.

Cmn
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
inline Transition<T>
@ExperimentalTransitionApi
@Composable
<S : Any?, T : Any?> Transition<S>.createChildTransition(
    label: String,
    transformToChildState: @Composable (parentState) -> T
)

createChildTransition creates a child Transition based on the mapping between parent state to child state provided in transformToChildState.

Cmn
V
<T : Any?, V : AnimationVector> TwoWayConverter<T, V>.createZeroVectorFrom(
    value: T
)

Creates an AnimationVector with all the values set to 0 using the provided TwoWayConverter and the value.

Cmn
DecayAnimationSpec<T>

Creates a DecayAnimationSpec from a FloatDecayAnimationSpec by applying the given FloatDecayAnimationSpec on every dimension of the AnimationVector that T converts to.

Cmn
T
<T : Any?, V : AnimationVector> Animation<T, V>.getVelocityFromNanos(
    playTimeNanos: Long
)

Returns the velocity of the animation at the given play time.

Cmn

Top-level properties summary

Easing

Easing Curve that speeds up quickly and ends slowly.

Cmn
Easing

Easing Curve that starts slowly and ends quickly.

Cmn
Easing

EaseInBack Curve

Cmn
Easing

EaseInBounce Curve

Cmn
Easing

EaseInCirc Curve

Cmn
Easing

EaseInCubic Curve

Cmn
Easing

EaseInElastic Curve

Cmn
Easing

EaseInExpo Curve

Cmn
Easing

Easing Curve that starts slowly, speeds up and then ends slowly.

Cmn
Easing

EaseInOutBack Curve

Cmn
Easing

EaseInOutBounce Curve

Cmn
Easing

EaseInOutCirc Curve

Cmn
Easing

EaseInOutCubic Curve

Cmn
Easing

EaseInOutElastic Curve

Cmn
Easing

EaseInOutExpo Curve

Cmn
Easing

EaseInOutQuad Curve

Cmn
Easing

EaseInOutQuart Curve

Cmn
Easing

EaseInOutQuint Curve

Cmn
Easing

EaseInOutSine Curve

Cmn
Easing

EaseInQuad Curve

Cmn
Easing

EaseInQuart Curve

Cmn
Easing

EaseInQuint Curve

Cmn
Easing

Easing Curve that starts slowly and ends quickly.

Cmn
Easing

Easing Curve that starts quickly and ends slowly.

Cmn
Easing

EaseOutBack Curve

Cmn
Easing

EaseOutBounce Curve

Cmn
Easing

EaseOutCirc Curve

Cmn
Easing

EaseOutCubic Curve

Cmn
Easing

EaseOutElastic Curve

Cmn
Easing

EaseOutExpo Curve

Cmn
Easing

EaseOutQuad Curve

Cmn
Easing

EaseOutQuart Curve

Cmn
Easing

EaseOutQuint Curve

Cmn
Easing

EaseOutSine Curve

Cmn
Easing

Elements exiting a screen use acceleration easing, where they start at rest and end at peak velocity.

Cmn
Easing

Elements that begin and end at rest use this standard easing.

Cmn
Easing

It returns fraction unmodified.

Cmn
Easing

Incoming elements are animated using deceleration easing, which starts a transition at peak velocity (the fastest point of an element’s movement) and ends at rest.

Cmn

Extension properties summary

TwoWayConverter<OffsetAnimationVector2D>

A type converter that converts a Offset to a AnimationVector2D, and vice versa.

Cmn
TwoWayConverter<RectAnimationVector4D>

A type converter that converts a Rect to a AnimationVector4D, and vice versa.

Cmn
TwoWayConverter<SizeAnimationVector2D>

A type converter that converts a Size to a AnimationVector2D, and vice versa.

Cmn
TwoWayConverter<DpAnimationVector1D>

A type converter that converts a Dp to a AnimationVector1D, and vice versa.

Cmn
TwoWayConverter<DpOffsetAnimationVector2D>

A type converter that converts a DpOffset to a AnimationVector2D, and vice versa.

Cmn
TwoWayConverter<IntOffsetAnimationVector2D>

A type converter that converts a IntOffset to a AnimationVector2D, and vice versa.

Cmn
TwoWayConverter<IntSizeAnimationVector2D>

A type converter that converts a IntSize to a AnimationVector2D, and vice versa.

Cmn
TwoWayConverter<FloatAnimationVector1D>

A TwoWayConverter that converts Float from and to AnimationVector1D

Cmn
TwoWayConverter<IntAnimationVector1D>

A TwoWayConverter that converts Int from and to AnimationVector1D

Cmn
Offset

Visibility threshold for Offset.

Cmn
Rect

Visibility threshold for Rect.

Cmn
Size

Visibility threshold for Size.

Cmn
Dp

Visibility threshold for Dp.

Cmn
DpOffset

Visibility threshold for DpOffset.

Cmn
IntOffset

Visibility threshold for IntOffset.

Cmn
IntSize

Visibility threshold for IntSize.

Cmn
Int

Visibility threshold for Int.

Cmn
Boolean

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

Cmn

Top-level functions

Animatable

fun Animatable(
    initialValue: Float,
    visibilityThreshold: Float = Spring.DefaultDisplacementThreshold
): Animatable<FloatAnimationVector1D>

This Animatable function creates a float value holder that automatically animates its value when the value is changed via animateTo. Animatable supports value change during an ongoing value change animation. When that happens, a new animation will transition Animatable from its current value (i.e. value at the point of interruption) to the new target. This ensures that the value change is always continuous using animateTo. If spring animation (i.e. default animation) is used with animateTo, the velocity change will be guaranteed to be continuous as well.

Unlike AnimationState, Animatable ensures mutual exclusiveness on its animation. To do so, when a new animation is started via animateTo (or animateDecay), any ongoing animation job will be cancelled.

import androidx.compose.animation.core.Animatable
import androidx.compose.animation.core.tween
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.remember
import androidx.compose.ui.composed
import androidx.compose.ui.graphics.graphicsLayer

fun Modifier.fadeIn(): Modifier = composed {
    // Creates an `Animatable` and remembers it.
    val alphaAnimation = remember { Animatable(0f) }
    // Launches a coroutine for the animation when entering the composition.
    // Uses `alphaAnimation` as the subject so the job in `LaunchedEffect` will run only when
    // `alphaAnimation` is created, which happens one time when the modifier enters
    // composition.
    LaunchedEffect(alphaAnimation) {
        // Animates to 1f from 0f for the fade-in, and uses a 500ms tween animation.
        alphaAnimation.animateTo(
            targetValue = 1f,
            // Default animationSpec uses [spring] animation, here we overwrite the default.
            animationSpec = tween(500)
        )
    }
    this.graphicsLayer(alpha = alphaAnimation.value)
}
Parameters
initialValue: Float

initial value of the animatable value holder

visibilityThreshold: Float = Spring.DefaultDisplacementThreshold

Threshold at which the animation may round off to its target value. Spring.DefaultDisplacementThreshold by default.

AnimationState

fun AnimationState(
    initialValue: Float,
    initialVelocity: Float = 0.0f,
    lastFrameTimeNanos: Long = AnimationConstants.UnspecifiedTime,
    finishedTimeNanos: Long = AnimationConstants.UnspecifiedTime,
    isRunning: Boolean = false
): AnimationState<FloatAnimationVector1D>

Factory method for creating an AnimationState for Float initialValue.

Parameters
initialValue: Float

initial value of the AnimationState

initialVelocity: Float = 0.0f

initial velocity of the AnimationState, 0 (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 by default.

isRunning: Boolean = false

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

AnimationState

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

Factory method for creating an AnimationState with an initialValue and an initialVelocity.

Parameters
typeConverter: TwoWayConverter<T, V>

TwoWayConverter to convert type T from and to AnimationVector

initialValue: T

initial value of the AnimationState

initialVelocity: T

initial velocity of the AnimationState

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 by default.

isRunning: Boolean = false

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

Returns
AnimationState<T, V>

A new AnimationState instance

AnimationVector

fun AnimationVector(v1: Float): AnimationVector1D

Factory method to create an AnimationVector1D

Parameters
v1: Float

value to set on the value field of AnimationVector1D

AnimationVector

fun AnimationVector(v1: Float, v2: Float): AnimationVector2D

Factory method to create an AnimationVector2D

Parameters
v1: Float

value to set on the first dimension

v2: Float

value to set on the second dimension

AnimationVector

fun AnimationVector(v1: Float, v2: Float, v3: Float): AnimationVector3D

Factory method to create an AnimationVector3D

Parameters
v1: Float

value to set on the first dimension

v2: Float

value to set on the second dimension

v3: Float

value to set on the third dimension

AnimationVector

fun AnimationVector(v1: Float, v2: Float, v3: Float, v4: Float): AnimationVector4D

Factory method to create an AnimationVector4D

Parameters
v1: Float

value to set on the first dimension

v2: Float

value to set on the second dimension

v3: Float

value to set on the third dimension

v4: Float

value to set on the fourth dimension

DecayAnimation

fun DecayAnimation(
    animationSpec: FloatDecayAnimationSpec,
    initialValue: Float,
    initialVelocity: Float = 0.0f
): DecayAnimation<FloatAnimationVector1D>

DecayAnimation is an animation that slows down from initialVelocity as time goes on. DecayAnimation is stateless, and it does not have any concept of lifecycle. It serves as an animation calculation engine that supports convenient query of value/velocity given a play time. To achieve that, DecayAnimation stores all the animation related information: initialValue, initialVelocity, decay animation spec.

Note: Unless there's a need to control the timing manually, it's generally recommended to use higher level animation APIs that build on top DecayAnimation, such as Animatable.animateDecay, animateDecay, etc.

Parameters
animationSpec: FloatDecayAnimationSpec

decay animation that will be used

initialValue: Float

starting value that will be passed to the decay animation

initialVelocity: Float = 0.0f

starting velocity for the decay animation, 0f by default

TargetBasedAnimation

fun <T : Any?, V : AnimationVector> TargetBasedAnimation(
    animationSpec: AnimationSpec<T>,
    typeConverter: TwoWayConverter<T, V>,
    initialValue: T,
    targetValue: T,
    initialVelocity: T
): TargetBasedAnimation<T, V>

Creates a TargetBasedAnimation with the given start/end conditions of the animation, and the provided animationSpec.

The resulting Animation assumes that the start value and velocity, as well as end value do not change throughout the animation, and cache these values. This caching enables much more convenient query for animation value and velocity (where only playtime needs to be passed into the methods).

Note: When interruptions happen to the TargetBasedAnimation, a new instance should be created that use the current value and velocity as the starting conditions. This type of interruption handling is the default behavior for both Animatable and Transition. Consider using those APIs for the interruption handling, as well as built-in animation lifecycle management.

Parameters
animationSpec: AnimationSpec<T>

the AnimationSpec that will be used to calculate value/velocity

typeConverter: TwoWayConverter<T, V>

the TwoWayConverter that is used to convert animation type T from/to V

initialValue: T

the start value of the animation

targetValue: T

the end value of the animation

initialVelocity: T

the start velocity (of type T of the animation

TwoWayConverter

fun <T : Any?, V : AnimationVector> TwoWayConverter(
    convertToVector: (T) -> V,
    convertFromVector: (V) -> T
): TwoWayConverter<T, V>

Factory method to create a TwoWayConverter that converts a type T from and to an AnimationVector type.

Parameters
convertToVector: (T) -> V

converts from type T to AnimationVector

convertFromVector: (V) -> T

converts from AnimationVector to type T

suspend fun animate(
    initialValue: Float,
    targetValue: Float,
    initialVelocity: Float = 0.0f,
    animationSpec: AnimationSpec<Float> = spring(),
    block: (value: Float, velocity: Float) -> Unit
): Unit

Target based animation that animates from the given initialValue towards the targetValue, with an optional initialVelocity. By default, a spring will be used for the animation. An alternative animationSpec can be provided to replace the default spring.

This is a convenient method for Float animation. If there's a need to access more info related to the animation such as start time, target, etc, consider using AnimationState.animateTo. To animate non-Float data types, consider the animate overload/variant for generic types.

import androidx.compose.animation.core.animate
import androidx.compose.animation.core.infiniteRepeatable
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.runtime.LaunchedEffect
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.graphics.graphicsLayer

@Composable
fun InfiniteAnimationDemo() {
    // Create a mutable state for alpha, and update it in the animation.
    val alpha = remember { mutableStateOf(1f) }
    LaunchedEffect(Unit) {
        // Animate from 1f to 0f using an infinitely repeating animation
        animate(
            initialValue = 1f,
            targetValue = 0f,
            animationSpec = infiniteRepeatable(
                animation = tween(1000),
                repeatMode = RepeatMode.Reverse
            )
        ) { value, /* velocity */ _ ->
            // Update alpha mutable state with the current animation value
            alpha.value = value
        }
    }
    Box(Modifier.fillMaxSize()) {
        Icon(
            Icons.Filled.Favorite,
            contentDescription = null,
            modifier = Modifier.align(Alignment.Center)
                .graphicsLayer(
                    scaleX = 3.0f,
                    scaleY = 3.0f,
                    alpha = alpha.value
                ),
            tint = Color.Red
        )
    }
}
Parameters
initialVelocity: Float = 0.0f

The velocity to use for the animation. 0f by default.

animationSpec: AnimationSpec<Float> = spring()

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

block: (value: Float, velocity: Float) -> Unit

Will be invoked on every frame with the current value and velocity of the animation for that frame.

See also
animateTo
suspend fun <T : Any?, V : AnimationVector> animate(
    typeConverter: TwoWayConverter<T, V>,
    initialValue: T,
    targetValue: T,
    initialVelocity: T? = null,
    animationSpec: AnimationSpec<T> = spring(),
    block: (value, velocity) -> Unit
): Unit

Target based animation for animating any data type T, so long as T can be converted to an AnimationVector using typeConverter. The animation will start from the initialValue and animate to the targetValue value. The initialVelocity will be derived from an all-0 AnimationVector unless specified. animationSpec can be provided to create a specific look and feel for the animation. By default, a spring will be used.

This is a convenient method for target-based animation. If there's a need to access more info related to the animation such as start time, target, etc, consider using AnimationState.animateTo.

See also
animateTo

animateDecay

suspend fun animateDecay(
    initialValue: Float,
    initialVelocity: Float,
    animationSpec: FloatDecayAnimationSpec,
    block: (value: Float, velocity: Float) -> Unit
): Unit

Decay animation that slows down from the given initialVelocity starting at initialValue until the velocity reaches 0. This is often used after a fling gesture.

This is a convenient method for decay animation. If there's a need to access more info related to the animation such as start time, target, etc, consider using AnimationState.animateDecay.

Parameters
animationSpec: FloatDecayAnimationSpec

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

block: (value: Float, velocity: Float) -> Unit

Will be invoked on each animation frame with up-to-date value and velocity.

See also
animateDecay
@Composable
fun animateDpAsState(
    targetValue: Dp,
    animationSpec: AnimationSpec<Dp> = dpDefaultSpring,
    label: String = "DpAnimation",
    finishedListener: ((Dp) -> Unit)? = null
): State<Dp>

Fire-and-forget animation function for Dp. This Composable function is overloaded for different parameter types such as Float, Color, Offset, etc. When the provided targetValue is changed, the animation will run automatically. If there is already an animation in-flight when targetValue changes, the on-going animation will adjust course to animate towards the new target value.

animateDpAsState returns a State object. The value of the state object will continuously be updated by the animation until the animation finishes.

Note, animateDpAsState cannot be canceled/stopped without removing this composable function from the tree. See Animatable for cancelable animations.

import androidx.compose.animation.core.animateDpAsState
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.requiredHeight

@Composable
fun HeightAnimation(collapsed: Boolean) {
    // Animates a height of [Dp] type to different target values based on the [collapsed] flag.
    val height: Dp by animateDpAsState(if (collapsed) 10.dp else 20.dp)
    Box(Modifier.fillMaxWidth().requiredHeight(height).background(color = Color.Red))
}
Parameters
targetValue: Dp

Target value of the animation

animationSpec: AnimationSpec<Dp> = dpDefaultSpring

The animation that will be used to change the value through time. Physics animation will be used by default.

label: String = "DpAnimation"

An optional label to differentiate from other animations in Android Studio.

finishedListener: ((Dp) -> Unit)? = null

An optional end listener to get notified when the animation is finished.

Returns
State<Dp>

A State object, the value of which is updated by animation.

animateFloatAsState

@Composable
fun animateFloatAsState(
    targetValue: Float,
    animationSpec: AnimationSpec<Float> = defaultAnimation,
    visibilityThreshold: Float = 0.01f,
    label: String = "FloatAnimation",
    finishedListener: ((Float) -> Unit)? = null
): State<Float>

Fire-and-forget animation function for Float. This Composable function is overloaded for different parameter types such as Dp, Color, Offset, etc. When the provided targetValue is changed, the animation will run automatically. If there is already an animation in-flight when targetValue changes, the on-going animation will adjust course to animate towards the new target value.

animateFloatAsState returns a State object. The value of the state object will continuously be updated by the animation until the animation finishes.

Note, animateFloatAsState cannot be canceled/stopped without removing this composable function from the tree. See Animatable for cancelable animations.

import androidx.compose.animation.core.animateFloatAsState
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.ui.graphics.graphicsLayer

@Composable
fun alphaAnimation(visible: Boolean) {
    // Animates to 1f or 0f based on [visible].
    // This [animateState] returns a State<Float> object. The value of the State object is
    // being updated by animation. (This method is overloaded for different parameter types.)
    // Here we use the returned [State] object as a property delegate.
    val alpha: Float by animateFloatAsState(if (visible) 1f else 0f)

    // Updates the alpha of a graphics layer with the float animation value. It is more
    // performant to modify alpha in a graphics layer than using `Modifier.alpha`. The former
    // limits the invalidation scope of alpha change to graphicsLayer's draw stage (i.e. no
    // recomposition would be needed). The latter triggers recomposition on each animation
    // frame.
    Box(modifier = Modifier.graphicsLayer { this.alpha = alpha }.background(Color.Red))
}
Parameters
targetValue: Float

Target value of the animation

animationSpec: AnimationSpec<Float> = defaultAnimation

The animation that will be used to change the value through time. spring will be used by default.

visibilityThreshold: Float = 0.01f

An optional threshold for deciding when the animation value is considered close enough to the targetValue.

label: String = "FloatAnimation"

An optional label to differentiate from other animations in Android Studio.

finishedListener: ((Float) -> Unit)? = null

An optional end listener to get notified when the animation is finished.

Returns
State<Float>

A State object, the value of which is updated by animation.

animateIntAsState

@Composable
fun animateIntAsState(
    targetValue: Int,
    animationSpec: AnimationSpec<Int> = intDefaultSpring,
    label: String = "IntAnimation",
    finishedListener: ((Int) -> Unit)? = null
): State<Int>

Fire-and-forget animation function for Int. This Composable function is overloaded for different parameter types such as Dp, Color, Offset, etc. When the provided targetValue is changed, the animation will run automatically. If there is already an animation in-flight when targetValue changes, the on-going animation will adjust course to animate towards the new target value.

animateIntAsState returns a State object. The value of the state object will continuously be updated by the animation until the animation finishes.

Note, animateIntAsState cannot be canceled/stopped without removing this composable function from the tree. See Animatable for cancelable animations.

Parameters
targetValue: Int

Target value of the animation

animationSpec: AnimationSpec<Int> = intDefaultSpring

The animation that will be used to change the value through time. Physics animation will be used by default.

label: String = "IntAnimation"

An optional label to differentiate from other animations in Android Studio.

finishedListener: ((Int) -> Unit)? = null

An optional end listener to get notified when the animation is finished.

Returns
State<Int>

A State object, the value of which is updated by animation.

animateIntOffsetAsState

@Composable
fun animateIntOffsetAsState(
    targetValue: IntOffset,
    animationSpec: AnimationSpec<IntOffset> = intOffsetDefaultSpring,
    label: String = "IntOffsetAnimation",
    finishedListener: ((IntOffset) -> Unit)? = null
): State<IntOffset>

Fire-and-forget animation function for IntOffset. This Composable function is overloaded for different parameter types such as Dp, Color, Offset, etc. When the provided targetValue is changed, the animation will run automatically. If there is already an animation in-flight when targetValue changes, the on-going animation will adjust course to animate towards the new target value.

animateIntOffsetAsState returns a State object. The value of the state object will continuously be updated by the animation until the animation finishes.

Note, animateIntOffsetAsState cannot be canceled/stopped without removing this composable function from the tree. See Animatable for cancelable animations.

import androidx.compose.animation.core.animateIntOffsetAsState
import androidx.compose.animation.core.animateOffsetAsState
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.unit.IntOffset

@Composable
fun OffsetAnimation(selected: Boolean) {
    // Animates the offset depending on the selected flag.
    // [animateOffsetAsState] returns a State<Offset> object. The value of the State object is
    // updated by the animation. Here we use that State<Offset> as a property delegate.
    val offset: Offset by animateOffsetAsState(
        if (selected) Offset(0f, 0f) else Offset(20f, 20f)
    )

    // In this example, animateIntOffsetAsState returns a State<IntOffset>. The value of the
    // returned
    // State object is updated by the animation.
    val intOffset: IntOffset by animateIntOffsetAsState(
        if (selected) IntOffset(0, 0) else IntOffset(50, 50)
    )
}
Parameters
targetValue: IntOffset

Target value of the animation

animationSpec: AnimationSpec<IntOffset> = intOffsetDefaultSpring

The animation that will be used to change the value through time. Physics animation will be used by default.

label: String = "IntOffsetAnimation"

An optional label to differentiate from other animations in Android Studio.

finishedListener: ((IntOffset) -> Unit)? = null

An optional end listener to get notified when the animation is finished.

Returns
State<IntOffset>

A State object, the value of which is updated by animation.

animateIntSizeAsState

@Composable
fun animateIntSizeAsState(
    targetValue: IntSize,
    animationSpec: AnimationSpec<IntSize> = intSizeDefaultSpring,
    label: String = "IntSizeAnimation",
    finishedListener: ((IntSize) -> Unit)? = null
): State<IntSize>

Fire-and-forget animation function for IntSize. This Composable function is overloaded for different parameter types such as Dp, Color, Offset, etc. When the provided targetValue is changed, the animation will run automatically. If there is already an animation in-flight when targetValue changes, the on-going animation will adjust course to animate towards the new target value.

animateIntSizeAsState returns a State object. The value of the state object will continuously be updated by the animation until the animation finishes.

Note, animateIntSizeAsState cannot be canceled/stopped without removing this composable function from the tree. See Animatable for cancelable animations.

Parameters
targetValue: IntSize

Target value of the animation

animationSpec: AnimationSpec<IntSize> = intSizeDefaultSpring

The animation that will be used to change the value through time. Physics animation will be used by default.

label: String = "IntSizeAnimation"

An optional label to differentiate from other animations in Android Studio.

finishedListener: ((IntSize) -> Unit)? = null

An optional end listener to get notified when the animation is finished.

Returns
State<IntSize>

A State object, the value of which is updated by animation.

animateOffsetAsState

@Composable
fun animateOffsetAsState(
    targetValue: Offset,
    animationSpec: AnimationSpec<Offset> = offsetDefaultSpring,
    label: String = "OffsetAnimation",
    finishedListener: ((Offset) -> Unit)? = null
): State<Offset>

Fire-and-forget animation function for Offset. This Composable function is overloaded for different parameter types such as Dp, Color, Float, etc. When the provided targetValue is changed, the animation will run automatically. If there is already an animation in-flight when targetValue changes, the on-going animation will adjust course to animate towards the new target value.

animateOffsetAsState returns a State object. The value of the state object will continuously be updated by the animation until the animation finishes.

Note, animateOffsetAsState cannot be canceled/stopped without removing this composable function from the tree. See Animatable for cancelable animations.

import androidx.compose.animation.core.animateIntOffsetAsState
import androidx.compose.animation.core.animateOffsetAsState
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.unit.IntOffset

@Composable
fun OffsetAnimation(selected: Boolean) {
    // Animates the offset depending on the selected flag.
    // [animateOffsetAsState] returns a State<Offset> object. The value of the State object is
    // updated by the animation. Here we use that State<Offset> as a property delegate.
    val offset: Offset by animateOffsetAsState(
        if (selected) Offset(0f, 0f) else Offset(20f, 20f)
    )

    // In this example, animateIntOffsetAsState returns a State<IntOffset>. The value of the
    // returned
    // State object is updated by the animation.
    val intOffset: IntOffset by animateIntOffsetAsState(
        if (selected) IntOffset(0, 0) else IntOffset(50, 50)
    )
}
Parameters
targetValue: Offset

Target value of the animation

animationSpec: AnimationSpec<Offset> = offsetDefaultSpring

The animation that will be used to change the value through time. Physics animation will be used by default.

label: String = "OffsetAnimation"

An optional label to differentiate from other animations in Android Studio.

finishedListener: ((Offset) -> Unit)? = null

An optional end listener to get notified when the animation is finished.

Returns
State<Offset>

A State object, the value of which is updated by animation.

animateRectAsState

@Composable
fun animateRectAsState(
    targetValue: Rect,
    animationSpec: AnimationSpec<Rect> = rectDefaultSpring,
    label: String = "RectAnimation",
    finishedListener: ((Rect) -> Unit)? = null
): State<Rect>

Fire-and-forget animation function for Rect. This Composable function is overloaded for different parameter types such as Dp, Color, Offset, etc. When the provided targetValue is changed, the animation will run automatically. If there is already an animation in-flight when targetValue changes, the on-going animation will adjust course to animate towards the new target value.

animateRectAsState returns a State object. The value of the state object will continuously be updated by the animation until the animation finishes.

Note, animateRectAsState cannot be canceled/stopped without removing this composable function from the tree. See Animatable for cancelable animations.

val bounds: Rect by animateRectAsState(
    if (enabled) Rect(0f, 0f, 100f, 100f) else Rect(8f, 8f, 80f, 80f))
Parameters
targetValue: Rect

Target value of the animation

animationSpec: AnimationSpec<Rect> = rectDefaultSpring

The animation that will be used to change the value through time. Physics animation will be used by default.

label: String = "RectAnimation"

An optional label to differentiate from other animations in Android Studio.

finishedListener: ((Rect) -> Unit)? = null

An optional end listener to get notified when the animation is finished.

Returns
State<Rect>

A State object, the value of which is updated by animation.

animateSizeAsState

@Composable
fun animateSizeAsState(
    targetValue: Size,
    animationSpec: AnimationSpec<Size> = sizeDefaultSpring,
    label: String = "SizeAnimation",
    finishedListener: ((Size) -> Unit)? = null
): State<Size>

Fire-and-forget animation function for Size. This Composable function is overloaded for different parameter types such as Dp, Color, Offset, etc. When the provided targetValue is changed, the animation will run automatically. If there is already an animation in-flight when targetValue changes, the on-going animation will adjust course to animate towards the new target value.

animateSizeAsState returns a State object. The value of the state object will continuously be updated by the animation until the animation finishes.

Note, animateSizeAsState cannot be canceled/stopped without removing this composable function from the tree. See Animatable for cancelable animations.

val size: Size by animateSizeAsState(
    if (selected) Size(20f, 20f) else Size(10f, 10f))
Parameters
targetValue: Size

Target value of the animation

animationSpec: AnimationSpec<Size> = sizeDefaultSpring

The animation that will be used to change the value through time. Physics animation will be used by default.

label: String = "SizeAnimation"

An optional label to differentiate from other animations in Android Studio.

finishedListener: ((Size) -> Unit)? = null

An optional end listener to get notified when the animation is finished.

Returns
State<Size>

A State object, the value of which is updated by animation.

animateValueAsState

@Composable
fun <T : Any?, V : AnimationVector> animateValueAsState(
    targetValue: T,
    typeConverter: TwoWayConverter<T, V>,
    animationSpec: AnimationSpec<T> = remember { spring() },
    visibilityThreshold: T? = null,
    label: String = "ValueAnimation",
    finishedListener: ((T) -> Unit)? = null
): State<T>

Fire-and-forget animation function for any value. This Composable function is overloaded for different parameter types such as Dp, Color, Offset, etc. When the provided targetValue is changed, the animation will run automatically. If there is already an animation in-flight when targetValue changes, the on-going animation will adjust course to animate towards the new target value.

animateValueAsState returns a State object. The value of the state object will continuously be updated by the animation until the animation finishes.

Note, animateValueAsState cannot be canceled/stopped without removing this composable function from the tree. See Animatable for cancelable animations.

import androidx.compose.animation.core.AnimationVector2D
import androidx.compose.animation.core.TwoWayConverter
import androidx.compose.animation.core.animateValueAsState
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.size
import androidx.compose.runtime.remember

@Composable
fun ArbitraryValueTypeAnimation(enabled: Boolean) {
    // Sets up the different animation target values based on the [enabled] flag.
    val mySize = remember(enabled) {
        if (enabled) {
            MySize(500.dp, 500.dp)
        } else {
            MySize(100.dp, 100.dp)
        }
    }

    // Animates a custom type value to the given target value, using a [TwoWayConverter]. The
    // converter tells the animation system how to convert the custom type from and to
    // [AnimationVector], so that it can be animated.
    val animSize: MySize by animateValueAsState(
        mySize,
        TwoWayConverter<MySize, AnimationVector2D>(
            convertToVector = { AnimationVector2D(it.width.value, it.height.value) },
            convertFromVector = { MySize(it.v1.dp, it.v2.dp) }
        )
    )
    Box(Modifier.size(animSize.width, animSize.height).background(color = Color.Red))
}
data class MySize(val width: Dp, val height: Dp)
Parameters
targetValue: T

Target value of the animation

animationSpec: AnimationSpec<T> = remember { spring() }

The animation that will be used to change the value through time. Physics animation will be used by default.

visibilityThreshold: T? = null

An optional threshold to define when the animation value can be considered close enough to the targetValue to end the animation.

label: String = "ValueAnimation"

An optional label to differentiate from other animations in Android Studio.

finishedListener: ((T) -> Unit)? = null

An optional end listener to get notified when the animation is finished.

Returns
State<T>

A State object, the value of which is updated by animation.

exponentialDecay

fun <T : Any?> exponentialDecay(
    frictionMultiplier: @FloatRange(from = 0.0, fromInclusive = false) Float = 1.0f,
    absVelocityThreshold: @FloatRange(from = 0.0, fromInclusive = false) Float = 0.1f
): DecayAnimationSpec<T>

Creates a decay animation spec where the friction/deceleration is always proportional to the velocity. As a result, the velocity goes under an exponential decay. The constructor parameter, frictionMultiplier, can be tuned to adjust the amount of friction applied in the decay. The higher the multiplier, the higher the friction, the sooner the animation will stop, and the shorter distance the animation will travel with the same starting condition. absVelocityThreshold describes the absolute value of a velocity threshold, below which the animation is considered finished.

Parameters
frictionMultiplier: @FloatRange(from = 0.0, fromInclusive = false) Float = 1.0f

The decay friction multiplier. This must be greater than 0.

absVelocityThreshold: @FloatRange(from = 0.0, fromInclusive = false) Float = 0.1f

The minimum speed, below which the animation is considered finished. Must be greater than 0.

infiniteRepeatable

fun <T : Any?> infiniteRepeatable(
    animation: DurationBasedAnimationSpec<T>,
    repeatMode: RepeatMode = RepeatMode.Restart,
    initialStartOffset: StartOffset = StartOffset(0)
): InfiniteRepeatableSpec<T>

Creates a InfiniteRepeatableSpec that plays a DurationBasedAnimationSpec (e.g. TweenSpec, KeyframesSpec) infinite amount of iterations.

For non-infinitely repeating animations, consider repeatable.

initialStartOffset can be used to either delay the start of the animation or to fast forward the animation to a given play time. This start offset will not be repeated, whereas the delay in the animation (if any) will be repeated. By default, the amount of offset is 0.

import androidx.compose.animation.core.StartOffset
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.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.ui.graphics.graphicsLayer

// This is an infinite progress indicator with 3 pulsing dots that grow and shrink.
@Composable
fun Dot(scale: State<Float>) {
    Box(
        Modifier.padding(5.dp).size(20.dp).graphicsLayer {
            scaleX = scale.value
            scaleY = scale.value
        }.background(Color.Gray, shape = CircleShape)
    )
}

val infiniteTransition = rememberInfiniteTransition()
val scale1 = infiniteTransition.animateFloat(
    0.2f,
    1f,
    // No offset for the 1st animation
    infiniteRepeatable(tween(600), RepeatMode.Reverse)
)
val scale2 = infiniteTransition.animateFloat(
    0.2f,
    1f,
    infiniteRepeatable(
        tween(600), RepeatMode.Reverse,
        // Offsets the 2nd animation by starting from 150ms of the animation
        // This offset will not be repeated.
        initialStartOffset = StartOffset(offsetMillis = 150, StartOffsetType.FastForward)
    )
)
val scale3 = infiniteTransition.animateFloat(
    0.2f,
    1f,
    infiniteRepeatable(
        tween(600), RepeatMode.Reverse,
        // Offsets the 3rd animation by starting from 300ms of the animation. This
        // offset will be not repeated.
        initialStartOffset = StartOffset(offsetMillis = 300, StartOffsetType.FastForward)
    )
)
Row {
    Dot(scale1)
    Dot(scale2)
    Dot(scale3)
}
Parameters
animation: DurationBasedAnimationSpec<T>

animation that will be repeated

repeatMode: RepeatMode = RepeatMode.Restart

whether animation should repeat by starting from the beginning (i.e. RepeatMode.Restart) or from the end (i.e. RepeatMode.Reverse)

initialStartOffset: StartOffset = StartOffset(0)

offsets the start of the animation

fun <T : Any?> keyframes(init: KeyframesSpec.KeyframesSpecConfig<T>.() -> Unit): KeyframesSpec<T>

Creates a KeyframesSpec animation, initialized with init. For example:

import androidx.compose.animation.core.keyframes

keyframes {
    0f at 0 // ms  // Optional
    0.4f at 75 // ms
    0.4f at 225 // ms
    0f at 375 // ms  // Optional
    durationMillis = 375
}

Keyframes can also be associated with a particular Easing function:

import androidx.compose.animation.core.keyframes

// Use FastOutSlowInEasing for the interval from 0 to 50 ms, and LinearOutSlowInEasing for the
// time between 50 and 100ms
keyframes<Float> {
    durationMillis = 100
    0f at 0 using FastOutSlowInEasing
    1.5f at 50 using LinearOutSlowInEasing
    1f at 100
}

Values can be animated using arcs of quarter of an Ellipse with KeyframesSpecConfig.using and ArcMode:

import androidx.compose.animation.core.keyframes
import androidx.compose.ui.geometry.Offset

keyframes<Offset> {
    // Animate for 1.2 seconds
    durationMillis = 1200

    // Animate to Offset(100f, 100f) at 50% of the animation using LinearEasing then, animate
    // using ArcAbove for the rest of the animation
    Offset(100f, 100f) atFraction 0.5f using LinearEasing using ArcAbove
}
Parameters
init: KeyframesSpec.KeyframesSpecConfig<T>.() -> Unit

Initialization function for the KeyframesSpec animation

keyframesWithSpline

@ExperimentalAnimationSpecApi
fun <T : Any?> keyframesWithSpline(init: KeyframesWithSplineSpec.KeyframesWithSplineSpecConfig<T>.() -> Unit): KeyframesWithSplineSpec<T>

Creates a KeyframesWithSplineSpec animation, initialized with init. For example:

import androidx.compose.animation.core.keyframesWithSpline
import androidx.compose.ui.geometry.Offset

keyframesWithSpline {
    durationMillis = 200
    Offset(0f, 0f) at 0
    Offset(500f, 100f) at 100
    Offset(400f, 50f) at 150
}
import androidx.compose.animation.core.keyframesWithSpline
import androidx.compose.ui.unit.IntOffset

keyframesWithSpline {
    durationMillis = 200
    IntOffset(0, 0) at 0
    IntOffset(500, 100) at 100
    IntOffset(400, 50) at 150
}
import androidx.compose.animation.core.keyframesWithSpline
import androidx.compose.ui.unit.DpOffset

keyframesWithSpline {
    durationMillis = 200
    DpOffset(0.dp, 0.dp) at 0
    DpOffset(500.dp, 100.dp) at 100
    DpOffset(400.dp, 50.dp) at 150
}
Parameters
init: KeyframesWithSplineSpec.KeyframesWithSplineSpecConfig<T>.() -> Unit

Initialization function for the KeyframesWithSplineSpec animation

rememberInfiniteTransition

@Composable
fun rememberInfiniteTransition(label: String = "InfiniteTransition"): InfiniteTransition

Creates a InfiniteTransition that runs infinite 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.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.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
        )
    }
}
Parameters
label: String = "InfiniteTransition"

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

rememberTransition

@Composable
fun <T : Any?> rememberTransition(
    transitionState: TransitionState<T>,
    label: String? = null
): Transition<T>

Creates a Transition and puts it in the currentState of the provided transitionState. If the TransitionState.targetState changes, the Transition will change where it will animate to.

Remember: The provided transitionState needs to be remembered.

Compared to updateTransition that takes a targetState, this function supports a different initial state than the first targetState. Here is an example:

import androidx.compose.animation.core.MutableTransitionState
import androidx.compose.animation.core.animateDp
import androidx.compose.animation.core.animateFloat
import androidx.compose.animation.core.rememberTransition
import androidx.compose.animation.core.spring
import androidx.compose.animation.core.tween
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.size
import androidx.compose.material.Card
import androidx.compose.runtime.remember
import androidx.compose.ui.graphics.graphicsLayer

// This composable enters the composition with a custom enter transition. This is achieved by
// defining a different initialState than the first target state using `MutableTransitionState`
@Composable
fun PoppingInCard() {
    // Creates a transition state with an initial state where visible = false
    val visibleState = remember { MutableTransitionState(false) }
    // Sets the target state of the transition state to true. As it's different than the initial
    // state, a transition from not visible to visible will be triggered.
    visibleState.targetState = true

    // Creates a transition with the transition state created above.
    val transition = rememberTransition(visibleState)
    // Adds a scale animation to the transition to scale the card up when transitioning in.
    val scale by transition.animateFloat(
        // Uses a custom spring for the transition.
        transitionSpec = { spring(dampingRatio = Spring.DampingRatioMediumBouncy) }
    ) { visible ->
        if (visible) 1f else 0.8f
    }
    // Adds an elevation animation that animates the dp value of the animation.
    val elevation by transition.animateDp(
        // Uses a tween animation
        transitionSpec = {
            // Uses different animations for when animating from visible to not visible, and
            // the other way around
            if (false isTransitioningTo true) {
                tween(1000)
            } else {
                spring()
            }
        }
    ) { visible ->
        if (visible) 10.dp else 0.dp
    }

    Card(
        Modifier
            .graphicsLayer(scaleX = scale, scaleY = scale)
            .size(200.dp, 100.dp)
            .fillMaxWidth(),
        elevation = elevation
    ) {}
}

In most cases, it is recommended to reuse the same transitionState that is remembered, such that Transition preserves continuity when targetState is changed. However, in some rare cases it is more critical to immediately snap to a state change (e.g. in response to a user interaction). This can be achieved by creating a new transitionState:

import androidx.compose.animation.core.MutableTransitionState
import androidx.compose.animation.core.animateFloat
import androidx.compose.animation.core.keyframes
import androidx.compose.animation.core.rememberTransition
import androidx.compose.animation.core.snap
import androidx.compose.animation.core.spring
import androidx.compose.animation.core.tween
import androidx.compose.foundation.gestures.detectTapGestures
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material.Icon
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.input.pointer.pointerInput

// enum class LikedStates { Initial, Liked, Disappeared }
@Composable
fun doubleTapToLike() {
    // Creates a transition state that starts in [Disappeared] State
    var transitionState by remember {
        mutableStateOf(MutableTransitionState(LikedStates.Disappeared))
    }

    Box(
        Modifier
            .fillMaxSize()
            .pointerInput(Unit) {
                detectTapGestures(
                    onDoubleTap = {
                        // This creates a new `MutableTransitionState` object. When a new
                        // `MutableTransitionState` object gets passed to `updateTransition`, a
                        // new transition will be created. All existing values, velocities will
                        // be lost as a result. Hence, in most cases, this is not recommended.
                        // The exception is when it's more important to respond immediately to
                        // user interaction than preserving continuity.
                        transitionState = MutableTransitionState(LikedStates.Initial)
                    }
                )
            }
    ) {
        // This ensures sequential states: Initial -> Liked -> Disappeared
        if (transitionState.currentState == LikedStates.Initial) {
            transitionState.targetState = LikedStates.Liked
        } else if (transitionState.currentState == LikedStates.Liked) {
            // currentState will be updated to targetState when the transition is finished, so
            // it can be used as a signal to start the next transition.
            transitionState.targetState = LikedStates.Disappeared
        }

        // Creates a transition using the TransitionState object that gets recreated at each
        // double tap.
        val transition = rememberTransition(transitionState)
        // Creates an alpha animation, as a part of the transition.
        val alpha by transition.animateFloat(
            transitionSpec = {
                when {
                    // Uses different animation specs for transitioning from/to different states
                    LikedStates.Initial isTransitioningTo LikedStates.Liked ->
                        keyframes {
                            durationMillis = 500
                            0f at 0 // optional
                            0.5f at 100
                            1f at 225 // optional
                        }
                    LikedStates.Liked isTransitioningTo LikedStates.Disappeared ->
                        tween(durationMillis = 200)
                    else -> snap()
                }
            }
        ) {
            if (it == LikedStates.Liked) 1f else 0f
        }

        // Creates a scale animation, as a part of the transition
        val scale by transition.animateFloat(
            transitionSpec = {
                when {
                    // Uses different animation specs for transitioning from/to different states
                    LikedStates.Initial isTransitioningTo LikedStates.Liked ->
                        spring(dampingRatio = Spring.DampingRatioHighBouncy)
                    LikedStates.Liked isTransitioningTo LikedStates.Disappeared ->
                        tween(200)
                    else -> snap()
                }
            }
        ) {
            when (it) {
                LikedStates.Initial -> 0f
                LikedStates.Liked -> 4f
                LikedStates.Disappeared -> 2f
            }
        }

        Icon(
            Icons.Filled.Favorite,
            "Like",
            Modifier
                .align(Alignment.Center)
                .graphicsLayer(
                    alpha = alpha,
                    scaleX = scale,
                    scaleY = scale
                ),
            tint = Color.Red
        )
    }
}
fun <T : Any?> repeatable(
    iterations: Int,
    animation: DurationBasedAnimationSpec<T>,
    repeatMode: RepeatMode = RepeatMode.Restart,
    initialStartOffset: StartOffset = StartOffset(0)
): RepeatableSpec<T>

Creates a RepeatableSpec that plays a DurationBasedAnimationSpec (e.g. TweenSpec, KeyframesSpec) the amount of iterations specified by iterations.

The iteration count describes the amount of times the animation will run. 1 means no repeat. Recommend infiniteRepeatable for creating an infinity repeating animation.

Note: When repeating in the RepeatMode.Reverse mode, it's highly recommended to have an odd number of iterations. Otherwise, the animation may jump to the end value when it finishes the last iteration.

initialStartOffset can be used to either delay the start of the animation or to fast forward the animation to a given play time. This start offset will not be repeated, whereas the delay in the animation (if any) will be repeated. By default, the amount of offset is 0.

Parameters
iterations: Int

the total count of iterations, should be greater than 1 to repeat.

animation: DurationBasedAnimationSpec<T>

animation that will be repeated

repeatMode: RepeatMode = RepeatMode.Restart

whether animation should repeat by starting from the beginning (i.e. RepeatMode.Restart) or from the end (i.e. RepeatMode.Reverse)

initialStartOffset: StartOffset = StartOffset(0)

offsets the start of the animation

fun <T : Any?> snap(delayMillis: Int = 0): SnapSpec<T>

Creates a Snap animation for immediately switching the animating value to the end value.

Parameters
delayMillis: Int = 0

the number of milliseconds to wait before the animation runs. 0 by default.

fun <T : Any?> spring(
    dampingRatio: Float = Spring.DampingRatioNoBouncy,
    stiffness: Float = Spring.StiffnessMedium,
    visibilityThreshold: T? = null
): SpringSpec<T>

Creates a SpringSpec that uses the given spring constants (i.e. dampingRatio and stiffness. The optional visibilityThreshold defines when the animation should be considered to be visually close enough to round off to its target.

Parameters
dampingRatio: Float = Spring.DampingRatioNoBouncy

damping ratio of the spring. Spring.DampingRatioNoBouncy by default.

stiffness: Float = Spring.StiffnessMedium

stiffness of the spring. Spring.StiffnessMedium by default.

visibilityThreshold: T? = null

optionally specifies the visibility threshold.

fun <T : Any?> tween(
    durationMillis: Int = DefaultDurationMillis,
    delayMillis: Int = 0,
    easing: Easing = FastOutSlowInEasing
): TweenSpec<T>

Creates a TweenSpec configured with the given duration, delay and easing curve.

Parameters
durationMillis: Int = DefaultDurationMillis

duration of the animation spec

delayMillis: Int = 0

the amount of time in milliseconds that animation waits before starting

easing: Easing = FastOutSlowInEasing

the easing curve that will be used to interpolate between start and end

updateTransition

@Composable
fun <T : Any?> updateTransition(targetState: T, label: String? = null): Transition<T>

This sets up a Transition, and updates it with the target provided by targetState. When targetState changes, Transition will run all of its child animations towards their target values specified for the new targetState. Child animations can be dynamically added using Transition.animateFloat, animateColor, Transition.animateValue, etc.

label is used to differentiate different transitions in Android Studio.

Note: There is another rememberTransition overload that accepts a MutableTransitionState. The difference between the two is that the MutableTransitionState variant: 1) supports a different initial state than target state (This would allow a transition to start as soon as it enters composition.) 2) can be recreated to intentionally trigger a re-start of the transition.

import androidx.compose.animation.animateColor
import androidx.compose.animation.core.animateFloat
import androidx.compose.animation.core.spring
import androidx.compose.animation.core.tween
import androidx.compose.animation.core.updateTransition
import androidx.compose.foundation.background
import androidx.compose.foundation.gestures.detectTapGestures
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.material.Button
import androidx.compose.material.Text
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.input.pointer.pointerInput

// enum class ComponentState { Pressed, Released }
var useRed by remember { mutableStateOf(false) }
var toState by remember { mutableStateOf(ComponentState.Released) }
val modifier = Modifier.pointerInput(Unit) {
    detectTapGestures(
        onPress = {
            toState = ComponentState.Pressed
            tryAwaitRelease()
            toState = ComponentState.Released
        }
    )
}

// Defines a transition of `ComponentState`, and updates the transition when the provided
// [targetState] changes. The transition will run all of the child animations towards the new
// [targetState] in response to the [targetState] change.
val transition: Transition<ComponentState> = updateTransition(targetState = toState)
// Defines a float animation as a child animation the transition. The current animation value
// can be read from the returned State<Float>.
val scale: Float by transition.animateFloat(
    // Defines a transition spec that uses the same low-stiffness spring for *all*
    // transitions of this float, no matter what the target is.
    transitionSpec = { spring(stiffness = 50f) }
) { state ->
    // This code block declares a mapping from state to value.
    if (state == ComponentState.Pressed) 3f else 1f
}

// Defines a color animation as a child animation of the transition.
val color: Color by transition.animateColor(
    transitionSpec = {
        when {
            ComponentState.Pressed isTransitioningTo ComponentState.Released ->
                // Uses spring for the transition going from pressed to released
                spring(stiffness = 50f)
            else ->
                // Uses tween for all the other transitions. (In this case there is
                // only one other transition. i.e. released -> pressed.)
                tween(durationMillis = 500)
        }
    }
) { state ->
    when (state) {
        // Similar to the float animation, we need to declare the target values
        // for each state. In this code block we can access theme colors.
        ComponentState.Pressed -> MaterialTheme.colors.primary
        // We can also have the target value depend on other mutableStates,
        // such as `useRed` here. Whenever the target value changes, transition
        // will automatically animate to the new value even if it has already
        // arrived at its target state.
        ComponentState.Released -> if (useRed) Color.Red else MaterialTheme.colors.secondary
    }
}
Column {
    Button(
        modifier = Modifier
            .padding(10.dp)
            .align(Alignment.CenterHorizontally),
        onClick = { useRed = !useRed }
    ) {
        Text("Change Color")
    }
    Box(
        modifier
            .fillMaxSize()
            .wrapContentSize(Alignment.Center)
            .size((100 * scale).dp)
            .background(color)
    )
}
Returns
Transition<T>

a Transition object, to which animations can be added.

updateTransition

@Composable
fun <T : Any?> updateTransition(
    transitionState: MutableTransitionState<T>,
    label: String? = null
): Transition<T>

Creates a Transition and puts it in the currentState of the provided transitionState. Whenever the targetState of the transitionState changes, the Transition will animate to the new target state.

Remember: The provided transitionState needs to be remembered.

Compared to the rememberTransition variant that takes a targetState, this function supports a different initial state than the first targetState. Here is an example:

import androidx.compose.animation.core.MutableTransitionState
import androidx.compose.animation.core.animateDp
import androidx.compose.animation.core.animateFloat
import androidx.compose.animation.core.rememberTransition
import androidx.compose.animation.core.spring
import androidx.compose.animation.core.tween
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.size
import androidx.compose.material.Card
import androidx.compose.runtime.remember
import androidx.compose.ui.graphics.graphicsLayer

// This composable enters the composition with a custom enter transition. This is achieved by
// defining a different initialState than the first target state using `MutableTransitionState`
@Composable
fun PoppingInCard() {
    // Creates a transition state with an initial state where visible = false
    val visibleState = remember { MutableTransitionState(false) }
    // Sets the target state of the transition state to true. As it's different than the initial
    // state, a transition from not visible to visible will be triggered.
    visibleState.targetState = true

    // Creates a transition with the transition state created above.
    val transition = rememberTransition(visibleState)
    // Adds a scale animation to the transition to scale the card up when transitioning in.
    val scale by transition.animateFloat(
        // Uses a custom spring for the transition.
        transitionSpec = { spring(dampingRatio = Spring.DampingRatioMediumBouncy) }
    ) { visible ->
        if (visible) 1f else 0.8f
    }
    // Adds an elevation animation that animates the dp value of the animation.
    val elevation by transition.animateDp(
        // Uses a tween animation
        transitionSpec = {
            // Uses different animations for when animating from visible to not visible, and
            // the other way around
            if (false isTransitioningTo true) {
                tween(1000)
            } else {
                spring()
            }
        }
    ) { visible ->
        if (visible) 10.dp else 0.dp
    }

    Card(
        Modifier
            .graphicsLayer(scaleX = scale, scaleY = scale)
            .size(200.dp, 100.dp)
            .fillMaxWidth(),
        elevation = elevation
    ) {}
}

In most cases, it is recommended to reuse the same transitionState that is remembered, such that Transition preserves continuity when targetState is changed. However, in some rare cases it is more critical to immediately snap to a state change (e.g. in response to a user interaction). This can be achieved by creating a new transitionState:

import androidx.compose.animation.core.MutableTransitionState
import androidx.compose.animation.core.animateFloat
import androidx.compose.animation.core.keyframes
import androidx.compose.animation.core.rememberTransition
import androidx.compose.animation.core.snap
import androidx.compose.animation.core.spring
import androidx.compose.animation.core.tween
import androidx.compose.foundation.gestures.detectTapGestures
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material.Icon
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.input.pointer.pointerInput

// enum class LikedStates { Initial, Liked, Disappeared }
@Composable
fun doubleTapToLike() {
    // Creates a transition state that starts in [Disappeared] State
    var transitionState by remember {
        mutableStateOf(MutableTransitionState(LikedStates.Disappeared))
    }

    Box(
        Modifier
            .fillMaxSize()
            .pointerInput(Unit) {
                detectTapGestures(
                    onDoubleTap = {
                        // This creates a new `MutableTransitionState` object. When a new
                        // `MutableTransitionState` object gets passed to `updateTransition`, a
                        // new transition will be created. All existing values, velocities will
                        // be lost as a result. Hence, in most cases, this is not recommended.
                        // The exception is when it's more important to respond immediately to
                        // user interaction than preserving continuity.
                        transitionState = MutableTransitionState(LikedStates.Initial)
                    }
                )
            }
    ) {
        // This ensures sequential states: Initial -> Liked -> Disappeared
        if (transitionState.currentState == LikedStates.Initial) {
            transitionState.targetState = LikedStates.Liked
        } else if (transitionState.currentState == LikedStates.Liked) {
            // currentState will be updated to targetState when the transition is finished, so
            // it can be used as a signal to start the next transition.
            transitionState.targetState = LikedStates.Disappeared
        }

        // Creates a transition using the TransitionState object that gets recreated at each
        // double tap.
        val transition = rememberTransition(transitionState)
        // Creates an alpha animation, as a part of the transition.
        val alpha by transition.animateFloat(
            transitionSpec = {
                when {
                    // Uses different animation specs for transitioning from/to different states
                    LikedStates.Initial isTransitioningTo LikedStates.Liked ->
                        keyframes {
                            durationMillis = 500
                            0f at 0 // optional
                            0.5f at 100
                            1f at 225 // optional
                        }
                    LikedStates.Liked isTransitioningTo LikedStates.Disappeared ->
                        tween(durationMillis = 200)
                    else -> snap()
                }
            }
        ) {
            if (it == LikedStates.Liked) 1f else 0f
        }

        // Creates a scale animation, as a part of the transition
        val scale by transition.animateFloat(
            transitionSpec = {
                when {
                    // Uses different animation specs for transitioning from/to different states
                    LikedStates.Initial isTransitioningTo LikedStates.Liked ->
                        spring(dampingRatio = Spring.DampingRatioHighBouncy)
                    LikedStates.Liked isTransitioningTo LikedStates.Disappeared ->
                        tween(200)
                    else -> snap()
                }
            }
        ) {
            when (it) {
                LikedStates.Initial -> 0f
                LikedStates.Liked -> 4f
                LikedStates.Disappeared -> 2f
            }
        }

        Icon(
            Icons.Filled.Favorite,
            "Like",
            Modifier
                .align(Alignment.Center)
                .graphicsLayer(
                    alpha = alpha,
                    scaleX = scale,
                    scaleY = scale
                ),
            tint = Color.Red
        )
    }
}

withInfiniteAnimationFrameMillis

suspend inline fun <R : Any?> withInfiniteAnimationFrameMillis(
    crossinline onFrame: (frameTimeMillis: Long) -> R
): R

Like withFrameMillis, but applies the InfiniteAnimationPolicy from the calling CoroutineContext if there is one.

withInfiniteAnimationFrameNanos

suspend fun <R : Any?> withInfiniteAnimationFrameNanos(
    onFrame: (frameTimeNanos: Long) -> R
): R

Like withFrameNanos, but applies the InfiniteAnimationPolicy from the calling CoroutineContext if there is one.

Extension functions

animateDecay

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.

@Composable
inline fun <S : Any?> Transition<S>.animateDp(
    noinline transitionSpec: @Composable Transition.Segment<S>.() -> FiniteAnimationSpec<Dp> = { spring(visibilityThreshold = Dp.VisibilityThreshold) },
    label: String = "DpAnimation",
    targetValueByState: @Composable (state) -> Dp
): State<Dp>

Creates a Dp 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
State<Dp>

A State object, the value of which is updated by animation

animateFloat

@Composable
inline fun <S : Any?> Transition<S>.animateFloat(
    noinline transitionSpec: @Composable Transition.Segment<S>.() -> FiniteAnimationSpec<Float> = { spring() },
    label: String = "FloatAnimation",
    targetValueByState: @Composable (state) -> 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.

import androidx.compose.animation.core.animateFloat
import androidx.compose.animation.core.keyframes
import androidx.compose.animation.core.snap
import androidx.compose.animation.core.tween
import androidx.compose.foundation.layout.Box
import androidx.compose.ui.graphics.graphicsLayer

// 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
    }
}

label is used to differentiate from other animations in the same transition in Android Studio.

Returns
State<Float>

A State object, the value of which is updated by animation

animateFloat

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

animateInt

@Composable
inline fun <S : Any?> Transition<S>.animateInt(
    noinline transitionSpec: @Composable Transition.Segment<S>.() -> FiniteAnimationSpec<Int> = { spring(visibilityThreshold = 1) },
    label: String = "IntAnimation",
    targetValueByState: @Composable (state) -> Int
): State<Int>

Creates a Int 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
State<Int>

A State object, the value of which is updated by animation

animateIntOffset

@Composable
inline fun <S : Any?> Transition<S>.animateIntOffset(
    noinline transitionSpec: @Composable Transition.Segment<S>.() -> FiniteAnimationSpec<IntOffset> = { spring(visibilityThreshold = IntOffset(1, 1)) },
    label: String = "IntOffsetAnimation",
    targetValueByState: @Composable (state) -> IntOffset
): State<IntOffset>

Creates a IntOffset 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
State<IntOffset>

A State object, the value of which is updated by animation

animateIntSize

@Composable
inline fun <S : Any?> Transition<S>.animateIntSize(
    noinline transitionSpec: @Composable Transition.Segment<S>.() -> FiniteAnimationSpec<IntSize> = { spring(visibilityThreshold = IntSize(1, 1)) },
    label: String = "IntSizeAnimation",
    targetValueByState: @Composable (state) -> IntSize
): State<IntSize>

Creates a IntSize 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
State<IntSize>

A State object, the value of which is updated by animation

animateOffset

@Composable
inline fun <S : Any?> Transition<S>.animateOffset(
    noinline transitionSpec: @Composable Transition.Segment<S>.() -> FiniteAnimationSpec<Offset> = { spring(visibilityThreshold = Offset.VisibilityThreshold) },
    label: String = "OffsetAnimation",
    targetValueByState: @Composable (state) -> Offset
): State<Offset>

Creates an Offset 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
State<Offset>

A State object, the value of which is updated by animation

animateRect

@Composable
inline fun <S : Any?> Transition<S>.animateRect(
    noinline transitionSpec: @Composable Transition.Segment<S>.() -> FiniteAnimationSpec<Rect> = { spring(visibilityThreshold = Rect.VisibilityThreshold) },
    label: String = "RectAnimation",
    targetValueByState: @Composable (state) -> Rect
): State<Rect>

Creates a Rect 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
State<Rect>

A State object, the value of which is updated by animation

animateSize

@Composable
inline fun <S : Any?> Transition<S>.animateSize(
    noinline transitionSpec: @Composable Transition.Segment<S>.() -> FiniteAnimationSpec<Size> = { spring(visibilityThreshold = Size.VisibilityThreshold) },
    label: String = "SizeAnimation",
    targetValueByState: @Composable (state) -> Size
): State<Size>

Creates a Size 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
State<Size>

A State object, the value of which is updated by animation

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.animateTo
import androidx.compose.animation.core.spring
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.

animateValue

@Composable
inline fun <S : Any?, T : Any?, V : AnimationVector> Transition<S>.animateValue(
    typeConverter: TwoWayConverter<T, V>,
    noinline transitionSpec: @Composable Transition.Segment<S>.() -> FiniteAnimationSpec<T> = { spring() },
    label: String = "ValueAnimation",
    targetValueByState: @Composable (state) -> T
): State<T>

Creates an animation of type T as a part of the given Transition. This means the states of this animation will be managed by the Transition. typeConverter will be used to convert between type T and AnimationVector so that the animation system knows how to animate it.

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
State<T>

A State object, the value of which is updated by animation

animateValue

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

// 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
}

calculateTargetValue

fun DecayAnimationSpec<Float>.calculateTargetValue(
    initialValue: Float,
    initialVelocity: Float
): Float

Calculates the target value of a Float decay animation based on the initialValue and initialVelocity.

Returns
Float

target value where the animation will come to a natural stop

calculateTargetValue

fun <T : Any?, V : AnimationVector> DecayAnimationSpec<T>.calculateTargetValue(
    typeConverter: TwoWayConverter<T, V>,
    initialValue: T,
    initialVelocity: T
): T

Calculates the target value of a decay animation based on the initialValue and initialVelocity, and the typeConverter that converts the given type T to AnimationVector.

Returns
T

target value where the animation will come to a natural stop

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

createChildTransition

@ExperimentalTransitionApi
@Composable
inline fun <S : Any?, T : Any?> Transition<S>.createChildTransition(
    label: String = "ChildTransition",
    transformToChildState: @Composable (parentState) -> T
): Transition<T>

createChildTransition creates a child Transition based on the mapping between parent state to child state provided in transformToChildState. This serves the following purposes:

  1. Hoist the child transition state into parent transition. Therefore the parent Transition will be aware of whether there's any on-going animation due to the same target state change. This will further allow sequential animation to be set up when all animations have finished.

  2. Separation of concerns. The child transition can respresent a much more simplified state transition when, for example, mapping from an enum parent state to a Boolean visible state for passing further down the compose tree. The child composables hence can be designed around handling a more simple and a more relevant state change.

label is used to differentiate from other animations in the same transition in Android Studio.

import androidx.compose.animation.core.animateDp
import androidx.compose.animation.core.animateFloat
import androidx.compose.animation.core.createChildTransition
import androidx.compose.animation.core.updateTransition
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.heightIn
import androidx.compose.foundation.layout.widthIn
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.draw.clip
import androidx.compose.ui.draw.scale

// enum class DialerState { DialerMinimized, NumberPad }
@OptIn(ExperimentalTransitionApi::class)
@Composable
fun DialerButton(visibilityTransition: Transition<Boolean>, modifier: Modifier) {
    val scale by visibilityTransition.animateFloat { visible ->
        if (visible) 1f else 2f
    }
    Box(
        modifier
            .scale(scale)
            .background(Color.Black)) {
        // Content goes here
    }
}

@Composable
fun NumberPad(visibilityTransition: Transition<Boolean>) {
    // Create animations using the provided Transition for visibility change here...
}

@OptIn(ExperimentalTransitionApi::class)
@Composable
fun childTransitionSample() {
    var dialerState by remember { mutableStateOf(DialerState.NumberPad) }
    Box(Modifier.fillMaxSize()) {
        val parentTransition = updateTransition(dialerState)

        // Animate to different corner radius based on target state
        val cornerRadius by parentTransition.animateDp {
            if (it == DialerState.NumberPad) 0.dp else 20.dp
        }

        Box(
            Modifier
                .align(Alignment.BottomCenter)
                .widthIn(50.dp)
                .heightIn(50.dp)
                .clip(RoundedCornerShape(cornerRadius))
        ) {
            NumberPad(
                // Creates a child transition that derives its target state from the parent
                // transition, and the mapping from parent state to child state.
                // This will allow:
                // 1) Parent transition to account for additional animations in the child
                // Transitions before it considers itself finished. This is useful when you
                // have a subsequent action after all animations triggered by a state change
                // have finished.
                // 2) Separation of concerns. This allows the child composable (i.e.
                // NumberPad) to only care about its own visibility, rather than knowing about
                // DialerState.
                visibilityTransition = parentTransition.createChildTransition {
                    // This is the lambda that defines how the parent target state maps to
                    // child target state.
                    it == DialerState.NumberPad
                }
                // Note: If it's not important for the animations within the child composable to
                // be observable, it's perfectly valid to not hoist the animations through
                // a Transition object and instead use animate*AsState.
            )
            DialerButton(
                visibilityTransition = parentTransition.createChildTransition {
                    it == DialerState.DialerMinimized
                },
                modifier = Modifier.matchParentSize()
            )
        }
    }
}

createZeroVectorFrom

fun <T : Any?, V : AnimationVector> TwoWayConverter<T, V>.createZeroVectorFrom(
    value: T
): V

Creates an AnimationVector with all the values set to 0 using the provided TwoWayConverter and the value.

Returns
V

a new AnimationVector instance of type V.

generateDecayAnimationSpec

fun <T : Any?> FloatDecayAnimationSpec.generateDecayAnimationSpec(): DecayAnimationSpec<T>

Creates a DecayAnimationSpec from a FloatDecayAnimationSpec by applying the given FloatDecayAnimationSpec on every dimension of the AnimationVector that T converts to.

getVelocityFromNanos

fun <T : Any?, V : AnimationVector> Animation<T, V>.getVelocityFromNanos(
    playTimeNanos: Long
): T

Returns the velocity of the animation at the given play time.

Parameters
playTimeNanos: Long

the play time that is used to calculate the velocity of the animation.

Top-level properties

val EaseEasing

Easing Curve that speeds up quickly and ends slowly.

Ease Curve

val EaseInEasing

Easing Curve that starts slowly and ends quickly.

EaseIn Curve

val EaseInOutEasing

Easing Curve that starts slowly, speeds up and then ends slowly.

EaseInOut Curve

EaseInOutBounce

val EaseInOutBounceEasing

EaseInOutBounce Curve

EaseInOutElastic

val EaseInOutElasticEasing

EaseInOutElastic Curve

EaseInSine

val EaseInSineEasing

Easing Curve that starts slowly and ends quickly. Similar to EaseIn, but with slightly less abrupt beginning

EaseInSine Curve

val EaseOutEasing

Easing Curve that starts quickly and ends slowly.

EaseOut Curve

FastOutLinearInEasing

val FastOutLinearInEasingEasing

Elements exiting a screen use acceleration easing, where they start at rest and end at peak velocity.

This is equivalent to the Android FastOutLinearInInterpolator

FastOutSlowInEasing

val FastOutSlowInEasingEasing

Elements that begin and end at rest use this standard easing. They speed up quickly and slow down gradually, in order to emphasize the end of the transition.

Standard easing puts subtle attention at the end of an animation, by giving more time to deceleration than acceleration. It is the most common form of easing.

This is equivalent to the Android FastOutSlowInInterpolator

LinearEasing

val LinearEasingEasing

It returns fraction unmodified. This is useful as a default value for cases where a Easing is required but no actual easing is desired.

LinearOutSlowInEasing

val LinearOutSlowInEasingEasing

Incoming elements are animated using deceleration easing, which starts a transition at peak velocity (the fastest point of an element’s movement) and ends at rest.

This is equivalent to the Android LinearOutSlowInInterpolator

Extension properties

VectorConverter

val Offset.Companion.VectorConverterTwoWayConverter<OffsetAnimationVector2D>

A type converter that converts a Offset to a AnimationVector2D, and vice versa.

VectorConverter

val Rect.Companion.VectorConverterTwoWayConverter<RectAnimationVector4D>

A type converter that converts a Rect to a AnimationVector4D, and vice versa.

VectorConverter

val Size.Companion.VectorConverterTwoWayConverter<SizeAnimationVector2D>

A type converter that converts a Size to a AnimationVector2D, and vice versa.

VectorConverter

val Dp.Companion.VectorConverterTwoWayConverter<DpAnimationVector1D>

A type converter that converts a Dp to a AnimationVector1D, and vice versa.

VectorConverter

val DpOffset.Companion.VectorConverterTwoWayConverter<DpOffsetAnimationVector2D>

A type converter that converts a DpOffset to a AnimationVector2D, and vice versa.

VectorConverter

val IntOffset.Companion.VectorConverterTwoWayConverter<IntOffsetAnimationVector2D>

A type converter that converts a IntOffset to a AnimationVector2D, and vice versa.

VectorConverter

val IntSize.Companion.VectorConverterTwoWayConverter<IntSizeAnimationVector2D>

A type converter that converts a IntSize to a AnimationVector2D, and vice versa.

VisibilityThreshold

val Offset.Companion.VisibilityThresholdOffset

Visibility threshold for Offset. This defines the amount of value change that is considered to be no longer visible. The animation system uses this to signal to some default spring animations to stop when the value is close enough to the target.

VisibilityThreshold

val Rect.Companion.VisibilityThresholdRect

Visibility threshold for Rect. This defines the amount of value change that is considered to be no longer visible. The animation system uses this to signal to some default spring animations to stop when the value is close enough to the target.

VisibilityThreshold

val Size.Companion.VisibilityThresholdSize

Visibility threshold for Size. This defines the amount of value change that is considered to be no longer visible. The animation system uses this to signal to some default spring animations to stop when the value is close enough to the target.

VisibilityThreshold

val Dp.Companion.VisibilityThresholdDp

Visibility threshold for Dp. This defines the amount of value change that is considered to be no longer visible. The animation system uses this to signal to some default spring animations to stop when the value is close enough to the target.

VisibilityThreshold

val DpOffset.Companion.VisibilityThresholdDpOffset

Visibility threshold for DpOffset. This defines the amount of value change that is considered to be no longer visible. The animation system uses this to signal to some default spring animations to stop when the value is close enough to the target.

VisibilityThreshold

val IntOffset.Companion.VisibilityThresholdIntOffset

Visibility threshold for IntOffset. This defines the amount of value change that is considered to be no longer visible. The animation system uses this to signal to some default spring animations to stop when the value is close enough to the target.

VisibilityThreshold

val IntSize.Companion.VisibilityThresholdIntSize

Visibility threshold for IntSize. This defines the amount of value change that is considered to be no longer visible. The animation system uses this to signal to some default spring animations to stop when the value is close enough to the target.

VisibilityThreshold

val Int.Companion.VisibilityThresholdInt

Visibility threshold for Int. This defines the amount of value change that is considered to be no longer visible. The animation system uses this to signal to some default spring animations to stop when the value is close enough to the target.

isFinished

val AnimationState<*, *>.isFinishedBoolean

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