Android 12 Developer Preview is here! Try it out, and give us your feedback!

AnimationResult

class AnimationResult<T, V : AnimationVector>
kotlin.Any
   ↳ androidx.compose.animation.core.AnimationResult

AnimationResult contains information about an animation at the end of the animation. endState captures the value/velocity/frame time, etc of the animation at its last frame. It can be useful for starting another animation to continue the velocity from the previously interrupted animation. endReason describes why the animation ended, it could be either of the following:

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

suspend fun CoroutineScope.animateBouncingOffBounds(
    animatable: Animatable<Offset, *>,
    flingVelocity: Offset,
    parentSize: Size
) {
    launch {
        var startVelocity = flingVelocity
        // Set bounds for the animation, so that when it reaches bounds it will stop
        // immediately. We can then inspect the returned `AnimationResult` and decide whether
        // we should start another animation.
        animatable.updateBounds(Offset(0f, 0f), Offset(parentSize.width, parentSize.height))
        do {
            val result = animatable.animateDecay(startVelocity, exponentialDecay())
            // Copy out the end velocity of the previous animation.
            startVelocity = result.endState.velocity

            // Negate the velocity for the dimension that hits the bounds, to create a
            // bouncing off the bounds effect.
            with(animatable) {
                if (value.x == upperBound?.x || value.x == lowerBound?.x) {
                    // x dimension hits bounds
                    startVelocity = startVelocity.copy(x = -startVelocity.x)
                }
                if (value.y == upperBound?.y || value.y == lowerBound?.y) {
                    // y dimension hits bounds
                    startVelocity = startVelocity.copy(y = -startVelocity.y)
                }
            }
            // Repeat the animation until the animation ends for reasons other than hitting
            // bounds, e.g. if `stop()` is called, or preempted by another animation.
        } while (result.endReason == AnimationEndReason.BoundReached)
    }
}

Summary

Public constructors
<init>(endState: AnimationState<T, V>, endReason: AnimationEndReason)

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

Properties
AnimationEndReason

The reason why the animation has ended.

AnimationState<T, V>

The state of the animation in its last frame before it's canceled or reset.

Public constructors

<init>

AnimationResult(
    endState: AnimationState<T, V>,
    endReason: AnimationEndReason)

AnimationResult contains information about an animation at the end of the animation. endState captures the value/velocity/frame time, etc of the animation at its last frame. It can be useful for starting another animation to continue the velocity from the previously interrupted animation. endReason describes why the animation ended, it could be either of the following:

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

suspend fun CoroutineScope.animateBouncingOffBounds(
    animatable: Animatable<Offset, *>,
    flingVelocity: Offset,
    parentSize: Size
) {
    launch {
        var startVelocity = flingVelocity
        // Set bounds for the animation, so that when it reaches bounds it will stop
        // immediately. We can then inspect the returned `AnimationResult` and decide whether
        // we should start another animation.
        animatable.updateBounds(Offset(0f, 0f), Offset(parentSize.width, parentSize.height))
        do {
            val result = animatable.animateDecay(startVelocity, exponentialDecay())
            // Copy out the end velocity of the previous animation.
            startVelocity = result.endState.velocity

            // Negate the velocity for the dimension that hits the bounds, to create a
            // bouncing off the bounds effect.
            with(animatable) {
                if (value.x == upperBound?.x || value.x == lowerBound?.x) {
                    // x dimension hits bounds
                    startVelocity = startVelocity.copy(x = -startVelocity.x)
                }
                if (value.y == upperBound?.y || value.y == lowerBound?.y) {
                    // y dimension hits bounds
                    startVelocity = startVelocity.copy(y = -startVelocity.y)
                }
            }
            // Repeat the animation until the animation ends for reasons other than hitting
            // bounds, e.g. if `stop()` is called, or preempted by another animation.
        } while (result.endReason == AnimationEndReason.BoundReached)
    }
}

Properties

endReason

val endReason: AnimationEndReason

The reason why the animation has ended. Could be either of the following:

endState

val endState: AnimationState<T, V>

The state of the animation in its last frame before it's canceled or reset. This captures the animation value/velocity/frame time, etc at the point of interruption, or before the velocity is reset when the animation finishes successfully.