Google is committed to advancing racial equity for Black communities. See how.

androidx.compose.animation

Classes

AnimatedFloatModel

Model class for AnimatedFloat.

AnimatedValueModel

Model class for AnimatedValue.

ColorPropKey

Built-in property key for Color properties.

DisposableAnimationClock

Clock that remembers all of its active subscriptions so that it can dispose of upstream subscriptions.

DpPropKey

Built-in property key for Dp properties.

EnterTransition

EnterTransition defines how an AnimatedVisibility Composable appears on screen as it becomes visible.

ExitTransition

ExitTransition defines how an AnimatedVisibility Composable disappears on screen as it becomes not visible.

OffsetPropKey

Built-in property key for Offset properties.

PxPropKey

Built-in property key for pixel properties.

RectPropKey

Built-in property key for Rect properties.

Annotations

ExperimentalAnimationApi

Top-level functions summary

Unit
AnimatedVisibility(visible: Boolean, modifier: Modifier = Modifier, enter: EnterTransition = fadeIn() + expandIn(), exit: ExitTransition = shrinkOut() + fadeOut(), initiallyVisible: Boolean = visible, content: () -> Unit)

AnimatedVisibility composable animates the appearance and disappearance of its content, as visible value changes.

Unit
Crossfade(current: T, modifier: Modifier = Modifier, animation: AnimationSpec<Float> = tween(), children: (T) -> Unit)

Crossfade allows to switch between two layouts with a crossfade animation.

Unit
Transition(definition: TransitionDefinition<T>, toState: T, clock: AnimationClockObservable = AnimationClockAmbient.current, initState: T = toState, onStateChangeFinished: (T) -> Unit = null, children: (state: TransitionState) -> Unit)

Deprecated: Transition has been deprecated.

Float
animate(target: Float, animSpec: AnimationSpec<Float> = defaultAnimation, visibilityThreshold: Float = 0.01f, endListener: (Float) -> Unit = null)

Fire-and-forget animation Composable for Float.

Color
animate(target: Color, animSpec: AnimationSpec<Color> = remember { SpringSpec() }, endListener: (Color) -> Unit = null)

Fire-and-forget animation Composable for Color.

Dp
animate(target: Dp, animSpec: AnimationSpec<Dp> = remember { SpringSpec(visibilityThreshold = DpVisibilityThreshold.dp) }, endListener: (Dp) -> Unit = null)

Fire-and-forget animation Composable for Dp.

Position
animate(target: Position, animSpec: AnimationSpec<Position> = remember { SpringSpec( visibilityThreshold = Position(DpVisibilityThreshold.dp, DpVisibilityThreshold.dp) ) }, endListener: (Position) -> Unit = null)

Fire-and-forget animation Composable for Position.

Size
animate(target: Size, animSpec: AnimationSpec<Size> = remember { SpringSpec(visibilityThreshold = Size(PxVisibilityThreshold, PxVisibilityThreshold)) }, endListener: (Size) -> Unit = null)

Fire-and-forget animation Composable for Size.

Bounds
animate(target: Bounds, animSpec: AnimationSpec<Bounds> = remember { SpringSpec( visibilityThreshold = Bounds.VectorConverter.convertFromVector (DpVisibilityThreshold4D) ) }, endListener: (Bounds) -> Unit = null)

Fire-and-forget animation Composable for Bounds.

Offset
animate(target: Offset, animSpec: AnimationSpec<Offset> = remember { SpringSpec(visibilityThreshold = Offset(PxVisibilityThreshold, PxVisibilityThreshold)) }, endListener: (Offset) -> Unit = null)

Fire-and-forget animation Composable for Offset.

Rect
animate(target: Rect, animSpec: AnimationSpec<Rect> = remember { SpringSpec( visibilityThreshold = Rect.VectorConverter.convertFromVector(PxVisibilityThreshold4D) ) }, endListener: (Rect) -> Unit = null)

Fire-and-forget animation Composable for Rect.

PxBounds
animate(target: PxBounds, animSpec: AnimationSpec<PxBounds> = remember { SpringSpec( visibilityThreshold = PxBounds.VectorConverter.convertFromVector(PxVisibilityThreshold4D) ) }, endListener: (PxBounds) -> Unit = null)

Fire-and-forget animation Composable for PxBounds.

Int
animate(target: Int, animSpec: AnimationSpec<Int> = remember { SpringSpec(visibilityThreshold = 1) }, endListener: (Int) -> Unit = null)

Fire-and-forget animation Composable for Int.

IntOffset
animate(target: IntOffset, animSpec: AnimationSpec<IntOffset> = remember { SpringSpec(visibilityThreshold = IntOffset(1, 1)) }, endListener: (IntOffset) -> Unit = null)

Fire-and-forget animation Composable for IntOffset.

IntSize
animate(target: IntSize, animSpec: AnimationSpec<IntSize> = remember { SpringSpec(visibilityThreshold = IntSize(1, 1)) }, endListener: (IntSize) -> Unit = null)

Fire-and-forget animation Composable for IntSize.

T
animate(target: T, animSpec: AnimationSpec<T> = remember { SpringSpec(visibilityThreshold = visibilityThreshold) }, visibilityThreshold: T? = null, endListener: (T) -> Unit = null)

Fire-and-forget animation Composable for AnimationVector.

T
animate(target: T, converter: TwoWayConverter<T, V>, animSpec: AnimationSpec<T> = remember { SpringSpec(visibilityThreshold = visibilityThreshold) }, visibilityThreshold: T? = null, endListener: (T) -> Unit = null)

Fire-and-forget animation Composable for any value.

AnimatedValue<Color, AnimationVector4D>
animatedColor(initVal: Color, clock: AnimationClockObservable = AnimationClockAmbient.current)

The animatedValue effect creates an AnimatedValue of Color and positionally memoizes it.

AnimatedFloat
animatedFloat(initVal: Float, visibilityThreshold: Float = Spring.DefaultDisplacementThreshold, clock: AnimationClockObservable = AnimationClockAmbient.current)

The animatedValue effect creates an AnimatedFloat and positionally memoizes it.

AnimatedValue<T, V>
animatedValue(initVal: T, converter: TwoWayConverter<T, V>, visibilityThreshold: T? = null, clock: AnimationClockObservable = AnimationClockAmbient.current)

The animatedValue effect creates an AnimatedValue and positionally memoizes it.

EnterTransition
expandHorizontally(expandFrom: Alignment.Horizontal = Alignment.End, initialWidth: (fullWidth: Int) -> Int = { 0 }, animSpec: AnimationSpec<IntSize> = spring(), clip: Boolean = true)

This expands the clip bounds of the appearing content horizontally, from the width returned from initialWidth to the full width.

EnterTransition
expandIn(expandFrom: Alignment = Alignment.BottomEnd, initialSize: (fullSize: IntSize) -> IntSize = { IntSize(0, 0) }, animSpec: AnimationSpec<IntSize> = spring(), clip: Boolean = true)

This expands the clip bounds of the appearing content from the size returned from initialSize to the full size.

EnterTransition
expandVertically(expandFrom: Alignment.Vertical = Alignment.Bottom, initialHeight: (fullHeight: Int) -> Int = { 0 }, animSpec: AnimationSpec<IntSize> = spring(), clip: Boolean = true)

This expands the clip bounds of the appearing content vertically, from the height returned from initialHeight to the full height.

EnterTransition
fadeIn(initialAlpha: Float = 0f, animSpec: AnimationSpec<Float> = spring())

This fades in the content of the transition, from the specified starting alpha (i.

ExitTransition
fadeOut(targetAlpha: Float = 0f, animSpec: AnimationSpec<Float> = spring())

This fades out the content of the transition, from full opacity to the specified target alpha (i.

ExitTransition
shrinkHorizontally(shrinkTowards: Alignment.Horizontal = Alignment.End, targetWidth: (fullWidth: Int) -> Int = { 0 }, animSpec: AnimationSpec<IntSize> = spring(), clip: Boolean = true)

This shrinks the clip bounds of the disappearing content horizontally, from the full width to the width returned from targetWidth.

ExitTransition
shrinkOut(shrinkTowards: Alignment = Alignment.BottomEnd, targetSize: (fullSize: IntSize) -> IntSize = { IntSize(0, 0) }, animSpec: AnimationSpec<IntSize> = spring(), clip: Boolean = true)

This shrinks the clip bounds of the disappearing content from the full size to the size returned from targetSize.

ExitTransition
shrinkVertically(shrinkTowards: Alignment.Vertical = Alignment.Bottom, targetHeight: (fullHeight: Int) -> Int = { 0 }, animSpec: AnimationSpec<IntSize> = spring(), clip: Boolean = true)

This shrinks the clip bounds of the disappearing content vertically, from the full height to the height returned from targetHeight.

EnterTransition
slideIn(initialOffset: (fullSize: IntSize) -> IntOffset, animSpec: AnimationSpec<IntOffset> = spring())

This slides in the content of the transition, from a starting offset defined in initialOffset to IntOffset(0, 0).

EnterTransition
slideInHorizontally(initialOffsetX: (fullWidth: Int) -> Int = { -it / 2 }, animSpec: AnimationSpec<IntOffset> = spring())

This slides in the content horizontally, from a starting offset defined in initialOffsetX to 0.

EnterTransition
slideInVertically(initialOffsetY: (fullHeight: Int) -> Int = { -it / 2 }, animSpec: AnimationSpec<IntOffset> = spring())

This slides in the content vertically, from a starting offset defined in initialOffsetY to 0.

ExitTransition
slideOut(targetOffset: (fullSize: IntSize) -> IntOffset, animSpec: AnimationSpec<IntOffset> = spring())

This slides out the content of the transition, from an offset of IntOffset(0, 0) to the target offset defined in targetOffset.

ExitTransition
slideOutHorizontally(targetOffsetX: (fullWidth: Int) -> Int = { -it / 2 }, animSpec: AnimationSpec<IntOffset> = spring())

This slides out the content horizontally, from 0 to a target offset defined in targetOffsetX.

ExitTransition
slideOutVertically(targetOffsetY: (fullHeight: Int) -> Int = { -it / 2 }, animSpec: AnimationSpec<IntOffset> = spring())

This slides out the content vertically, from 0 to a target offset defined in targetOffsetY.

TransitionState
transition(definition: TransitionDefinition<T>, toState: T, clock: AnimationClockObservable = AnimationClockAmbient.current, initState: T = toState, label: String? = null, onStateChangeFinished: (T) -> Unit = null)

transition composable creates a state-based transition using the animation configuration defined in TransitionDefinition.

Top-level properties summary

TwoWayConverter<Bounds, AnimationVector4D>

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

(colorSpace: ColorSpace) -> TwoWayConverter<Color, AnimationVector4D>

A lambda that takes a ColorSpace and returns a converter that can both convert a Color to a AnimationVector4D, and convert a AnimationVector4D) back to a Color in the given ColorSpace.

TwoWayConverter<Dp, AnimationVector1D>

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

TwoWayConverter<IntOffset, AnimationVector2D>

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

TwoWayConverter<IntSize, AnimationVector2D>

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

TwoWayConverter<Offset, AnimationVector2D>

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

TwoWayConverter<Position, AnimationVector2D>

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

TwoWayConverter<PxBounds, AnimationVector4D>

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

TwoWayConverter<Rect, AnimationVector4D>

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

TwoWayConverter<Size, AnimationVector2D>

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

Extension functions summary

For RowScope
Unit
RowScope.AnimatedVisibility(visible: Boolean, modifier: Modifier = Modifier, enter: EnterTransition = fadeIn() + expandHorizontally(), exit: ExitTransition = fadeOut() + shrinkHorizontally(), initiallyVisible: Boolean = visible, content: () -> Unit)

AnimatedVisibility composable animates the appearance and disappearance of its content, as visible value changes.

For ColumnScope
Unit
ColumnScope.AnimatedVisibility(visible: Boolean, modifier: Modifier = Modifier, enter: EnterTransition = fadeIn() + expandVertically(), exit: ExitTransition = fadeOut() + shrinkVertically(), initiallyVisible: Boolean = visible, content: () -> Unit)

AnimatedVisibility composable animates the appearance and disappearance of its content, as visible value changes.

For Modifier
Modifier
Modifier.animateContentSize(animSpec: AnimationSpec<IntSize> = spring(), clip: Boolean = true, endListener: (startSize: IntSize, endSize: IntSize) -> Unit = null)

This modifier animates its own size when its child modifier (or the child composable if it is already at the tail of the chain) changes size.

For AnimationClockObservable
DisposableAnimationClock

Return a new AnimationClockObservable wrapping this one that will auto-unsubscribe all AnimationClockObservers when this call leaves the composition, preventing clock subscriptions from persisting beyond the composition lifecycle.

Top-level functions

AnimatedVisibility

@Composable fun AnimatedVisibility(
    visible: Boolean,
    modifier: Modifier = Modifier,
    enter: EnterTransition = fadeIn() + expandIn(),
    exit: ExitTransition = shrinkOut() + fadeOut(),
    initiallyVisible: Boolean = visible,
    content: () -> Unit
): Unit

AnimatedVisibility composable animates the appearance and disappearance of its content, as visible value changes. Different EnterTransitions and ExitTransitions can be defined in enter and exit for the appearance and disappearance animation. There are 3 types of EnterTransition and ExitTransition: Fade, Expand/Shrink and Slide. The enter transitions and exit transitions can be combined using +. The order of the combination does not matter, as the transition animations will start simultaneously. See EnterTransition and ExitTransition for details on the three types of transition. Here's an example of combining all three types of transitions together:

import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.expandVertically
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.animation.shrinkVertically
import androidx.compose.animation.slideInVertically
import androidx.compose.animation.slideOutVertically
import androidx.compose.foundation.Text
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember

var visible by remember { mutableStateOf(true) }
AnimatedVisibility(
    visible = visible,
    enter = slideInVertically(
        // Start the slide from 40 (pixels) above where the content is supposed to go, to
        // produce a parallax effect
        initialOffsetY = { -40 }
    ) + expandVertically(
        expandFrom = Alignment.Top
    ) + fadeIn(initialAlpha = 0.3f),
    exit = slideOutVertically() + shrinkVertically() + fadeOut()
) {
    // Content that needs to appear/disappear goes here:
    Text("Content to appear/disappear", Modifier.fillMaxWidth().height(200.dp))
}

This composable function creates a custom Layout for its content. The size of the custom layout is determined by the largest width and largest height of the children. All children will be arranged in a box (aligned to the top start of the Layout).

Note: Once the exit transition is finished, the content composable will be skipped (i.e. the content will be removed from the tree, and disposed).

By default, the enter transition will be a combination of fading in and expanding the content in from the bottom end. And the exit transition will be shrinking the content towards the bottom end while fading out. The expanding and shrinking will likely also animate the parent and siblings if they rely on the size of appearing/disappearing content. When the AnimatedVisibility composable is put in a Row or a Column, the default enter and exit transitions are tailored to that particular container. See RowScope.AnimatedVisibility and ColumnScope.AnimatedVisibility for details.

initiallyVisible defaults to the same value as visible. This means when the AnimatedVisibility is first added to the tree, there is no appearing animation. If it is desired to show an appearing animation for the first appearance of the content, initiallyVisible can be set to false and visible to true.

Parameters
visible: Boolean defines whether the content should be visible
modifier: Modifier = Modifier modifier for the Layout created to contain the content
enter: EnterTransition = fadeIn() + expandIn() EnterTransitions used for the appearing animation, fading in while expanding by default
exit: ExitTransition = shrinkOut() + fadeOut() ExitTransition used for the disappearing animation, fading out while shrinking by default
initiallyVisible: Boolean = visible controls whether the first appearance should be animated, defaulting to match visible (i.e. not animating the first appearance)

Crossfade

@Composable fun <T> Crossfade(
    current: T,
    modifier: Modifier = Modifier,
    animation: AnimationSpec<Float> = tween(),
    children: (T) -> Unit
): Unit

Crossfade allows to switch between two layouts with a crossfade animation.

import androidx.compose.animation.Crossfade
import androidx.compose.foundation.Text

Crossfade(current = "A") { screen ->
    when (screen) {
        "A" -> Text("Page A")
        "B" -> Text("Page B")
    }
}
Parameters
current: T is a key representing your current layout state. every time you change a key the animation will be triggered. The children called with the old key will be faded out while the children called with the new key will be faded in.
modifier: Modifier = Modifier Modifier to be applied to the animation container.
animation: AnimationSpec<Float> = tween() the AnimationSpec to configure the animation.

Transition

@Composable fun <T> Transition(
    definition: TransitionDefinition<T>,
    toState: T,
    clock: AnimationClockObservable = AnimationClockAmbient.current,
    initState: T = toState,
    onStateChangeFinished: (T) -> Unit = null,
    children: (state: TransitionState) -> Unit
): Unit

Deprecated.

Deprecated: Transition has been deprecated. Please use transition instead.

Transition composable creates a state-based transition using the animation configuration defined in TransitionDefinition. This can be especially useful when animating multiple values from a predefined set of values to another. For animating a single value, consider using animatedValue, animatedFloat, animatedColor or the more light-weight animate APIs.

Transition starts a new animation or changes the on-going animation when the toState parameter is changed to a different value. It dutifully ensures that the animation will head towards new toState regardless of what state (or in-between state) it’s currently in: If the transition is not currently animating, having a new toState value will start a new animation, otherwise the in-flight animation will correct course and animate towards the new toState based on the interruption handling logic.

Transition takes a transition definition, a target state and child composables. These child composables will be receiving a TransitionState object as an argument, which captures all the current values of the animation. Child composables should read the animation values from the TransitionState object, and apply the value wherever necessary.

import androidx.compose.animation.ColorPropKey
import androidx.compose.animation.DpPropKey
import androidx.compose.animation.core.transitionDefinition
import androidx.compose.animation.transition
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.preferredSize

val colorKey = ColorPropKey()
val widthKey = DpPropKey()
val heightKey = DpPropKey()

val definition = transitionDefinition<State> {
    state(State.First) {
        this[colorKey] = Color.Red
        this[widthKey] = 200.dp
        this[heightKey] = 400.dp
    }
    state(State.Second) {
        this[colorKey] = Color.Green
        this[widthKey] = 300.dp
        this[heightKey] = 300.dp
    }
}

@Composable
fun TransitionBasedColoredRect() {
    // This puts the transition in State.First. Any subsequent state change will trigger a
    // transition animation, as defined in the transition definition.
    val state = transition(definition = definition, toState = State.First)
    Box(
        Modifier
            .preferredSize(state[widthKey], state[heightKey])
            .background(color = state[colorKey])
    )
}

@Composable
fun ColorRectWithInitState() {
    // This starts the transition going from State.First to State.Second when this composable
    // gets composed for the first time.
    val state = transition(
        definition = definition, initState = State.First, toState = State.Second
    )
    Box(
        Modifier
            .preferredSize(state[widthKey], state[heightKey])
            .background(state[colorKey])
    )
}
Parameters
definition: TransitionDefinition<T> Transition definition that defines states and transitions
toState: T New state to transition to
clock: AnimationClockObservable = AnimationClockAmbient.current Optional animation clock that pulses animations when time changes. By default, the system uses a choreographer based clock read from the AnimationClockAmbient. A custom implementation of the AnimationClockObservable (such as a androidx.compose.animation.core.ManualAnimationClock) can be supplied here if there’s a need to manually control the clock (for example in tests).
initState: T = toState Optional initial state for the transition. When undefined, the initial state will be set to the first toState seen in the transition.
onStateChangeFinished: (T) -> Unit = null An optional listener to get notified when state change animation has completed
children: (state: TransitionState) -> Unit The children composables that will be animated

animate

@Composable fun animate(
    target: Float,
    animSpec: AnimationSpec<Float> = defaultAnimation,
    visibilityThreshold: Float = 0.01f,
    endListener: (Float) -> Unit = null
): Float

Fire-and-forget animation Composable for Float. Once such an animation is created, it will be positionally memoized, like other @Composables. To trigger the animation, or alter the course of the animation, simply supply a different target to the Composable.

Note, animate is for simple animations that cannot be canceled. For cancellable animations see animatedFloat.

import androidx.compose.animation.animate
import androidx.compose.foundation.Text
import androidx.compose.ui.draw.drawOpacity

@Composable
fun VisibilityTransition(visible: Boolean) {
    val opacity = animate(if (visible) 0f else 1f)
    Text("Visibility Transition", modifier = Modifier.drawOpacity(opacity))
}
Parameters
target: Float Target value of the animation
animSpec: AnimationSpec<Float> = defaultAnimation The animation that will be used to change the value through time. SpringSpec will be used by default.
visibilityThreshold: Float = 0.01f An optional threshold for deciding when the animation value is considered close enough to the target.
endListener: (Float) -> Unit = null An optional end listener to get notified when the animation is finished.

animate

@Composable fun animate(
    target: Color,
    animSpec: AnimationSpec<Color> = remember { SpringSpec() },
    endListener: (Color) -> Unit = null
): Color

Fire-and-forget animation Composable for Color. Once such an animation is created, it will be positionally memoized, like other @Composables. To trigger the animation, or alter the course of the animation, simply supply a different target to the Composable.

Note, animate is for simple animations that cannot be canceled. For cancellable animations see animatedColor.

import androidx.compose.animation.animate
import androidx.compose.foundation.Text

@Composable
fun ColorTransition(enabled: Boolean) {
    val textColor = animate(if (enabled) Color.Black else Color.Gray)
    Text("Visibility Transition", color = textColor)
}
Parameters
target: Color Target value of the animation
animSpec: AnimationSpec<Color> = remember { SpringSpec() } The animation that will be used to change the value through time. Physics animation will be used by default.
endListener: (Color) -> Unit = null An optional end listener to get notified when the animation is finished.

animate

@Composable fun animate(
    target: Dp,
    animSpec: AnimationSpec<Dp> = remember { SpringSpec(visibilityThreshold = DpVisibilityThreshold.dp) },
    endListener: (Dp) -> Unit = null
): Dp

Fire-and-forget animation Composable for Dp. Once such an animation is created, it will be positionally memoized, like other @Composables. To trigger the animation, or alter the course of the animation, simply supply a different target to the Composable.

Note, animate is for simple animations that cannot be canceled. For cancellable animations see animatedValue.

import androidx.compose.animation.animate
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height

@Composable
fun HeightAnimation(collapsed: Boolean) {
    val height: Dp = animate(if (collapsed) 10.dp else 20.dp)
    Box(Modifier.fillMaxWidth().height(height).background(color = Color.Red))
}
Parameters
target: Dp Target value of the animation
animSpec: AnimationSpec<Dp> = remember { SpringSpec(visibilityThreshold = DpVisibilityThreshold.dp) } The animation that will be used to change the value through time. Physics animation will be used by default.
endListener: (Dp) -> Unit = null An optional end listener to get notified when the animation is finished.

animate

@Composable fun animate(
    target: Position,
    animSpec: AnimationSpec<Position> = remember { SpringSpec( visibilityThreshold = Position(DpVisibilityThreshold.dp, DpVisibilityThreshold.dp) ) },
    endListener: (Position) -> Unit = null
): Position

Fire-and-forget animation Composable for Position. Once such an animation is created, it will be positionally memoized, like other @Composables. To trigger the animation, or alter the course of the animation, simply supply a different target to the Composable.

Note, animate is for simple animations that cannot be canceled. For cancellable animations see animatedValue.

    val position : Position = animate(
        if (selected) Position(0.dp, 0.dp) else Position(20.dp, 20.dp))
Parameters
target: Position Target value of the animation
animSpec: AnimationSpec<Position> = remember { SpringSpec( visibilityThreshold = Position(DpVisibilityThreshold.dp, DpVisibilityThreshold.dp) ) } The animation that will be used to change the value through time. Physics animation will be used by default.
endListener: (Position) -> Unit = null An optional end listener to get notified when the animation is finished.

animate

@Composable fun animate(
    target: Size,
    animSpec: AnimationSpec<Size> = remember { SpringSpec(visibilityThreshold = Size(PxVisibilityThreshold, PxVisibilityThreshold)) },
    endListener: (Size) -> Unit = null
): Size

Fire-and-forget animation Composable for Size. Once such an animation is created, it will be positionally memoized, like other @Composables. To trigger the animation, or alter the course of the animation, simply supply a different target to the Composable.

Note, animate is for simple animations that cannot be canceled. For cancellable animations see animatedValue.

    val size : Size = animate(
        if (selected) Size(20f, 20f) else Size(10f, 10f))
Parameters
target: Size Target value of the animation
animSpec: AnimationSpec<Size> = remember { SpringSpec(visibilityThreshold = Size(PxVisibilityThreshold, PxVisibilityThreshold)) } The animation that will be used to change the value through time. Physics animation will be used by default.
endListener: (Size) -> Unit = null An optional end listener to get notified when the animation is finished.

animate

@Composable fun animate(
    target: Bounds,
    animSpec: AnimationSpec<Bounds> = remember { SpringSpec( visibilityThreshold = Bounds.VectorConverter.convertFromVector (DpVisibilityThreshold4D) ) },
    endListener: (Bounds) -> Unit = null
): Bounds

Fire-and-forget animation Composable for Bounds. Once such an animation is created, it will be positionally memoized, like other @Composables. To trigger the animation, or alter the course of the animation, simply supply a different target to the Composable.

Note, animate is for simple animations that cannot be canceled. For cancellable animations see animatedValue.

    val bounds : Bounds = animate(
        if (collapsed) Bounds(0.dp, 0.dp, 10.dp, 20.dp) else Bounds(0.dp, 0.dp, 100.dp, 200.dp))
Parameters
target: Bounds Target value of the animation
animSpec: AnimationSpec<Bounds> = remember { SpringSpec( visibilityThreshold = Bounds.VectorConverter.convertFromVector (DpVisibilityThreshold4D) ) } The animation that will be used to change the value through time. Physics animation will be used by default.
endListener: (Bounds) -> Unit = null An optional end listener to get notified when the animation is finished.

animate

@Composable fun animate(
    target: Offset,
    animSpec: AnimationSpec<Offset> = remember { SpringSpec(visibilityThreshold = Offset(PxVisibilityThreshold, PxVisibilityThreshold)) },
    endListener: (Offset) -> Unit = null
): Offset

Fire-and-forget animation Composable for Offset. Once such an animation is created, it will be positionally memoized, like other @Composables. To trigger the animation, or alter the course of the animation, simply supply a different target to the Composable.

Note, animate is for simple animations that cannot be canceled. For cancellable animations see animatedValue.

import androidx.compose.animation.animate
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.unit.IntOffset

@Composable
fun OffsetTransition(selected: Boolean) {
    val offset: Offset = animate(
        if (selected) Offset(0f, 0f) else Offset(20f, 20f)
    )

    val intOffset: IntOffset = animate(
        if (selected) IntOffset(0, 0) else IntOffset(50, 50)
    )
}
Parameters
target: Offset Target value of the animation
animSpec: AnimationSpec<Offset> = remember { SpringSpec(visibilityThreshold = Offset(PxVisibilityThreshold, PxVisibilityThreshold)) } The animation that will be used to change the value through time. Physics animation will be used by default.
endListener: (Offset) -> Unit = null An optional end listener to get notified when the animation is finished.

animate

@Composable fun animate(
    target: Rect,
    animSpec: AnimationSpec<Rect> = remember { SpringSpec( visibilityThreshold = Rect.VectorConverter.convertFromVector(PxVisibilityThreshold4D) ) },
    endListener: (Rect) -> Unit = null
): Rect

Fire-and-forget animation Composable for Rect. Once such an animation is created, it will be positionally memoized, like other @Composables. To trigger the animation, or alter the course of the animation, simply supply a different target to the Composable.

Note, animate is for simple animations that cannot be canceled. For cancellable animations see animatedValue.

    val bounds : Rect = animate(
        if (enabled) Rect(0f, 0f, 100f, 100f) else Rect(8f, 8f, 80f, 80f))
Parameters
target: Rect Target value of the animation
animSpec: AnimationSpec<Rect> = remember { SpringSpec( visibilityThreshold = Rect.VectorConverter.convertFromVector(PxVisibilityThreshold4D) ) } The animation that will be used to change the value through time. Physics animation will be used by default.
endListener: (Rect) -> Unit = null An optional end listener to get notified when the animation is finished.

animate

@Composable fun animate(
    target: PxBounds,
    animSpec: AnimationSpec<PxBounds> = remember { SpringSpec( visibilityThreshold = PxBounds.VectorConverter.convertFromVector(PxVisibilityThreshold4D) ) },
    endListener: (PxBounds) -> Unit = null
): PxBounds

Deprecated.

Fire-and-forget animation Composable for PxBounds. Once such an animation is created, it will be positionally memoized, like other @Composables. To trigger the animation, or alter the course of the animation, simply supply a different target to the Composable.

Note, animate is for simple animations that cannot be canceled. For cancellable animations see animatedValue.

    val bounds : PxBounds = animate(
        if (enabled) PxBounds(0.px, 0.px, 100.px, 100.px) else PxBounds(8.px, 8.px, 80.px, 80.px))
Parameters
target: PxBounds Target value of the animation
animSpec: AnimationSpec<PxBounds> = remember { SpringSpec( visibilityThreshold = PxBounds.VectorConverter.convertFromVector(PxVisibilityThreshold4D) ) } The animation that will be used to change the value through time. Physics animation will be used by default.
endListener: (PxBounds) -> Unit = null An optional end listener to get notified when the animation is finished.

animate

@Composable fun animate(
    target: Int,
    animSpec: AnimationSpec<Int> = remember { SpringSpec(visibilityThreshold = 1) },
    endListener: (Int) -> Unit = null
): Int

Fire-and-forget animation Composable for Int. Once such an animation is created, it will be positionally memoized, like other @Composables. To trigger the animation, or alter the course of the animation, simply supply a different target to the Composable.

Note, animate is for simple animations that cannot be canceled. For cancellable animations see animatedValue.

Parameters
target: Int Target value of the animation
animSpec: AnimationSpec<Int> = remember { SpringSpec(visibilityThreshold = 1) } The animation that will be used to change the value through time. Physics animation will be used by default.
endListener: (Int) -> Unit = null An optional end listener to get notified when the animation is finished.

animate

@Composable fun animate(
    target: IntOffset,
    animSpec: AnimationSpec<IntOffset> = remember { SpringSpec(visibilityThreshold = IntOffset(1, 1)) },
    endListener: (IntOffset) -> Unit = null
): IntOffset

Fire-and-forget animation Composable for IntOffset. Once such an animation is created, it will be positionally memoized, like other @Composables. To trigger the animation, or alter the course of the animation, simply supply a different target to the Composable.

Note, animate is for simple animations that cannot be canceled. For cancellable animations see animatedValue.

import androidx.compose.animation.animate
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.unit.IntOffset

@Composable
fun OffsetTransition(selected: Boolean) {
    val offset: Offset = animate(
        if (selected) Offset(0f, 0f) else Offset(20f, 20f)
    )

    val intOffset: IntOffset = animate(
        if (selected) IntOffset(0, 0) else IntOffset(50, 50)
    )
}
Parameters
target: IntOffset Target value of the animation
animSpec: AnimationSpec<IntOffset> = remember { SpringSpec(visibilityThreshold = IntOffset(1, 1)) } The animation that will be used to change the value through time. Physics animation will be used by default.
endListener: (IntOffset) -> Unit = null An optional end listener to get notified when the animation is finished.

animate

@Composable fun animate(
    target: IntSize,
    animSpec: AnimationSpec<IntSize> = remember { SpringSpec(visibilityThreshold = IntSize(1, 1)) },
    endListener: (IntSize) -> Unit = null
): IntSize

Fire-and-forget animation Composable for IntSize. Once such an animation is created, it will be positionally memoized, like other @Composables. To trigger the animation, or alter the course of the animation, simply supply a different target to the Composable.

Note, animate is for simple animations that cannot be canceled. For cancellable animations see animatedValue.

Parameters
target: IntSize Target value of the animation
animSpec: AnimationSpec<IntSize> = remember { SpringSpec(visibilityThreshold = IntSize(1, 1)) } The animation that will be used to change the value through time. Physics animation will be used by default.
endListener: (IntSize) -> Unit = null An optional end listener to get notified when the animation is finished.

animate

@Composable fun <T : AnimationVector> animate(
    target: T,
    animSpec: AnimationSpec<T> = remember { SpringSpec(visibilityThreshold = visibilityThreshold) },
    visibilityThreshold: T? = null,
    endListener: (T) -> Unit = null
): T

Fire-and-forget animation Composable for AnimationVector. Once such an animation is created, it will be positionally memoized, like other @Composables. To trigger the animation, or alter the course of the animation, simply supply a different target to the Composable.

Note, animate is for simple animations that cannot be canceled. For cancellable animations see animatedValue.

Parameters
target: T Target value of the animation
animSpec: AnimationSpec<T> = remember { SpringSpec(visibilityThreshold = visibilityThreshold) } 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 target to end the animation.
endListener: (T) -> Unit = null An optional end listener to get notified when the animation is finished.

animate

@Composable fun <T, V : AnimationVector> animate(
    target: T,
    converter: TwoWayConverter<T, V>,
    animSpec: AnimationSpec<T> = remember { SpringSpec(visibilityThreshold = visibilityThreshold) },
    visibilityThreshold: T? = null,
    endListener: (T) -> Unit = null
): T

Fire-and-forget animation Composable for any value. Once such an animation is created, it will be positionally memoized, like other @Composables. To trigger the animation, or alter the course of the animation, simply supply a different target to the Composable.

Note, animate is for simple animations that cannot be canceled. For cancellable animations see animatedValue.

import androidx.compose.animation.animate
import androidx.compose.animation.core.AnimationVector2D
import androidx.compose.animation.core.TwoWayConverter
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.preferredSize
import androidx.compose.runtime.remember

@Composable
fun ArbitraryValueTypeTransition(enabled: Boolean) {
    val mySize = remember(enabled) {
        if (enabled) {
            MySize(500.dp, 500.dp)
        } else {
            MySize(100.dp, 100.dp)
        }
    }
    val animSize = animate<MySize, AnimationVector2D>(
        mySize,
        TwoWayConverter(
            convertToVector = { AnimationVector2D(it.width.value, it.height.value) },
            convertFromVector = { MySize(it.v1.dp, it.v2.dp) }
        )
    )
    Box(Modifier.preferredSize(animSize.width, animSize.height).background(color = Color.Red))
}
    data class MySize(val width: Dp, val height: Dp)
Parameters
target: T Target value of the animation
animSpec: AnimationSpec<T> = remember { SpringSpec(visibilityThreshold = visibilityThreshold) } 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 target to end the animation.
endListener: (T) -> Unit = null An optional end listener to get notified when the animation is finished.

animatedColor

@Composable fun animatedColor(
    initVal: Color,
    clock: AnimationClockObservable = AnimationClockAmbient.current
): AnimatedValue<Color, AnimationVector4D>

The animatedValue effect creates an AnimatedValue of Color and positionally memoizes it. When the AnimatedValue object gets its value updated, components that rely on that value will be automatically recomposed.

Parameters
initVal: Color Initial value to set AnimatedValue to.

animatedFloat

@Composable fun animatedFloat(
    initVal: Float,
    visibilityThreshold: Float = Spring.DefaultDisplacementThreshold,
    clock: AnimationClockObservable = AnimationClockAmbient.current
): AnimatedFloat

The animatedValue effect creates an AnimatedFloat and positionally memoizes it. When the AnimatedFloat object gets its value updated, components that rely on that value will be automatically recomposed.

Parameters
initVal: Float Initial value to set AnimatedFloat to.

animatedValue

@Composable fun <T, V : AnimationVector> animatedValue(
    initVal: T,
    converter: TwoWayConverter<T, V>,
    visibilityThreshold: T? = null,
    clock: AnimationClockObservable = AnimationClockAmbient.current
): AnimatedValue<T, V>

The animatedValue effect creates an AnimatedValue and positionally memoizes it. When the AnimatedValue object gets its value updated, components that rely on that value will be automatically recomposed.

Parameters
initVal: T Initial value to set AnimatedValue to.
converter: TwoWayConverter<T, V> A value type converter for transforming any type T to an animatable type (i.e. Floats, Vector2D, Vector3D, etc)
visibilityThreshold: T? = null Visibility threshold for the animatedValue to consider itself finished.

expandHorizontally

@Stable fun expandHorizontally(
    expandFrom: Alignment.Horizontal = Alignment.End,
    initialWidth: (fullWidth: Int) -> Int = { 0 },
    animSpec: AnimationSpec<IntSize> = spring(),
    clip: Boolean = true
): EnterTransition

This expands the clip bounds of the appearing content horizontally, from the width returned from initialWidth to the full width. expandFrom controls which part of the content gets revealed first. By default, the clip bounds animates from 0 to full width, starting from the end of the content, and expand to fully revealing the whole content.

Note: expandHorizontally animates the bounds of the content. This bounds change will also result in the animation of other layouts that are dependent on this size.

initialWidth is a lambda that takes the full width of the content and returns an initial width of the bounds of the content. This allows not only an absolute width, but also an initial width that is proportional to the content width.

clip defines whether the content outside of the animated bounds should be clipped. By default, clip is set to true, which only shows content in the animated bounds.

import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.core.tween
import androidx.compose.animation.expandHorizontally
import androidx.compose.animation.shrinkHorizontally
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember

var visible by remember { mutableStateOf(true) }
AnimatedVisibility(
    visible = visible,
    enter = expandHorizontally(
        // Set the start width to 20 (pixels), 0 by default
        initialWidth = { 20 }
    ),
    exit = shrinkHorizontally(
        // Shrink towards the end (i.e. right edge for LTR, left edge for RTL). The default
        // direction for the shrink is towards [Alignment.Start]
        shrinkTowards = Alignment.End,
        // Set the end width for the shrink animation to a quarter of the full width.
        targetWidth = { fullWidth -> fullWidth / 4 },
        // Overwrites the default animation with tween for this shrink animation.
        animSpec = tween()
    )
) {
    // Content that needs to appear/disappear goes here:
    Box(Modifier.fillMaxWidth().height(200.dp))
}
Parameters
expandFrom: Alignment.Horizontal = Alignment.End the starting point of the expanding bounds, Alignment.End by default.
initialWidth: (fullWidth: Int) -> Int = { 0 } the start width of the expanding bounds, returning 0 by default.
animSpec: AnimationSpec<IntSize> = spring() the animation used for the expanding animation, spring by default.
clip: Boolean = true whether the content outside of the animated bounds should be clipped, true by default

expandIn

@Stable fun expandIn(
    expandFrom: Alignment = Alignment.BottomEnd,
    initialSize: (fullSize: IntSize) -> IntSize = { IntSize(0, 0) },
    animSpec: AnimationSpec<IntSize> = spring(),
    clip: Boolean = true
): EnterTransition

This expands the clip bounds of the appearing content from the size returned from initialSize to the full size. expandFrom controls which part of the content gets revealed first. By default, the clip bounds animates from IntSize(0, 0) to full size, starting from revealing the bottom right corner (or bottom left corner in RTL layouts) of the content, to fully revealing the entire content as the size expands.

Note: expandIn animates the bounds of the content. This bounds change will also result in the animation of other layouts that are dependent on this size.

initialSize is a lambda that takes the full size of the content and returns an initial size of the bounds of the content. This allows not only absolute size, but also an initial size that is proportional to the content size.

clip defines whether the content outside of the animated bounds should be clipped. By default, clip is set to true, which only shows content in the animated bounds.

For expanding only horizontally or vertically, consider expandHorizontally, expandVertically.

import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.core.tween
import androidx.compose.animation.expandIn
import androidx.compose.animation.shrinkOut
import androidx.compose.foundation.Text
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.unit.IntSize

var visible by remember { mutableStateOf(true) }

AnimatedVisibility(
    visible,
    enter = expandIn(
        // Overwrites the corner of the content that is first revealed
        expandFrom = Alignment.BottomStart,
        // Overwrites the initial size to 50 pixels by 50 pixels
        initialSize = { IntSize(50, 50) },
        // Overwrites the default spring animation with tween
        animSpec = tween(100, easing = LinearOutSlowInEasing)
    ),
    exit = shrinkOut(
        // Overwrites the area of the content that the shrink animation will end on. The
        // following parameters will shrink the content's clip bounds from the full size of the
        // content to 1/10 of the width and 1/5 of the height. The shrinking clip bounds will
        // always be aligned to the CenterStart of the full-content bounds.
        shrinkTowards = Alignment.CenterStart,
        // Overwrites the target size of the shrinking animation.
        targetSize = { fullSize -> IntSize(fullSize.width / 10, fullSize.height / 5) },
        animSpec = tween(100, easing = FastOutSlowInEasing)
    )
) {
    // Content that needs to appear/disappear goes here:
    Text("Content to appear/disappear", Modifier.fillMaxWidth().height(200.dp))
}
Parameters
expandFrom: Alignment = Alignment.BottomEnd the starting point of the expanding bounds, Alignment.BottomEnd by default.
initialSize: (fullSize: IntSize) -> IntSize = { IntSize(0, 0) } the start size of the expanding bounds, returning IntSize(0, 0) by default.
animSpec: AnimationSpec<IntSize> = spring() the animation used for the expanding animation, spring by default.
clip: Boolean = true whether the content outside of the animated bounds should be clipped, true by default

expandVertically

@Stable fun expandVertically(
    expandFrom: Alignment.Vertical = Alignment.Bottom,
    initialHeight: (fullHeight: Int) -> Int = { 0 },
    animSpec: AnimationSpec<IntSize> = spring(),
    clip: Boolean = true
): EnterTransition

This expands the clip bounds of the appearing content vertically, from the height returned from initialHeight to the full height. expandFrom controls which part of the content gets revealed first. By default, the clip bounds animates from 0 to full height, revealing the bottom edge first, followed by the rest of the content.

Note: expandVertically animates the bounds of the content. This bounds change will also result in the animation of other layouts that are dependent on this size.

initialHeight is a lambda that takes the full height of the content and returns an initial height of the bounds of the content. This allows not only an absolute height, but also an initial height that is proportional to the content height.

clip defines whether the content outside of the animated bounds should be clipped. By default, clip is set to true, which only shows content in the animated bounds.

import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.core.tween
import androidx.compose.animation.expandVertically
import androidx.compose.animation.shrinkVertically
import androidx.compose.foundation.Text
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember

var visible by remember { mutableStateOf(true) }

AnimatedVisibility(
    visible,
    // Sets the initial height of the content to 20, revealing only the top of the content at
    // the beginning of the expanding animation.
    enter = expandVertically(
        expandFrom = Alignment.Top,
        initialHeight = { 20 }
    ),
    // Shrinks the content to half of its full height via an animation.
    exit = shrinkVertically(
        targetHeight = { fullHeight -> fullHeight / 2 },
        animSpec = tween()
    )
) {
    // Content that needs to appear/disappear goes here:
    Text("Content to appear/disappear", Modifier.fillMaxWidth().height(200.dp))
}
Parameters
expandFrom: Alignment.Vertical = Alignment.Bottom the starting point of the expanding bounds, Alignment.Bottom by default.
initialHeight: (fullHeight: Int) -> Int = { 0 } the start height of the expanding bounds, returning 0 by default.
animSpec: AnimationSpec<IntSize> = spring() the animation used for the expanding animation, spring by default.
clip: Boolean = true whether the content outside of the animated bounds should be clipped, true by default

fadeIn

@Stable fun fadeIn(
    initialAlpha: Float = 0f,
    animSpec: AnimationSpec<Float> = spring()
): EnterTransition

This fades in the content of the transition, from the specified starting alpha (i.e. initialAlpha) to 1f, using the supplied animSpec. initialAlpha defaults to 0f, and spring is used by default.

import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.core.tween
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.foundation.Text
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember

var visible by remember { mutableStateOf(true) }
AnimatedVisibility(
    visible = visible,
    enter = fadeIn(
        // Overwrites the initial value of alpha to 0.4f for fade in, 0 by default
        initialAlpha = 0.4f
    ),
    exit = fadeOut(
        // Overwrites the default animation with tween
        animSpec = tween(durationMillis = 250)
    )
) {
    // Content that needs to appear/disappear goes here:
    Text("Content to appear/disappear", Modifier.fillMaxWidth().height(200.dp))
}
Parameters
initialAlpha: Float = 0f the starting alpha of the enter transition, 0f by default
animSpec: AnimationSpec<Float> = spring() the AnimationSpec for this animation, spring by default

fadeOut

@Stable fun fadeOut(
    targetAlpha: Float = 0f,
    animSpec: AnimationSpec<Float> = spring()
): ExitTransition

This fades out the content of the transition, from full opacity to the specified target alpha (i.e. targetAlpha), using the supplied animSpec. By default, the content will be faded out to fully transparent (i.e. targetAlpha defaults to 0), and animSpec uses spring by default.

import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.core.tween
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.foundation.Text
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember

var visible by remember { mutableStateOf(true) }
AnimatedVisibility(
    visible = visible,
    enter = fadeIn(
        // Overwrites the initial value of alpha to 0.4f for fade in, 0 by default
        initialAlpha = 0.4f
    ),
    exit = fadeOut(
        // Overwrites the default animation with tween
        animSpec = tween(durationMillis = 250)
    )
) {
    // Content that needs to appear/disappear goes here:
    Text("Content to appear/disappear", Modifier.fillMaxWidth().height(200.dp))
}
Parameters
targetAlpha: Float = 0f the target alpha of the exit transition, 0f by default
animSpec: AnimationSpec<Float> = spring() the AnimationSpec for this animation, spring by default

shrinkHorizontally

@Stable fun shrinkHorizontally(
    shrinkTowards: Alignment.Horizontal = Alignment.End,
    targetWidth: (fullWidth: Int) -> Int = { 0 },
    animSpec: AnimationSpec<IntSize> = spring(),
    clip: Boolean = true
): ExitTransition

This shrinks the clip bounds of the disappearing content horizontally, from the full width to the width returned from targetWidth. shrinkTowards controls the direction of the bounds shrink animation. By default, the clip bounds animates from full width to 0, shrinking towards the the end of the content.

Note: shrinkHorizontally animates the bounds of the content. This bounds change will also result in the animation of other layouts that are dependent on this size.

targetWidth is a lambda that takes the full width of the content and returns a target width of the content. This allows not only absolute width, but also a target width that is proportional to the content width.

clip defines whether the content outside of the animated bounds should be clipped. By default, clip is set to true, which only shows content in the animated bounds.

import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.core.tween
import androidx.compose.animation.expandHorizontally
import androidx.compose.animation.shrinkHorizontally
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember

var visible by remember { mutableStateOf(true) }
AnimatedVisibility(
    visible = visible,
    enter = expandHorizontally(
        // Set the start width to 20 (pixels), 0 by default
        initialWidth = { 20 }
    ),
    exit = shrinkHorizontally(
        // Shrink towards the end (i.e. right edge for LTR, left edge for RTL). The default
        // direction for the shrink is towards [Alignment.Start]
        shrinkTowards = Alignment.End,
        // Set the end width for the shrink animation to a quarter of the full width.
        targetWidth = { fullWidth -> fullWidth / 4 },
        // Overwrites the default animation with tween for this shrink animation.
        animSpec = tween()
    )
) {
    // Content that needs to appear/disappear goes here:
    Box(Modifier.fillMaxWidth().height(200.dp))
}
Parameters
shrinkTowards: Alignment.Horizontal = Alignment.End the ending point of the shrinking bounds, Alignment.End by default.
targetWidth: (fullWidth: Int) -> Int = { 0 } returns the end width of the shrinking bounds, 0 by default.
animSpec: AnimationSpec<IntSize> = spring() the animation used for the shrinking animation, spring by default.
clip: Boolean = true whether the content outside of the animated bounds should be clipped, true by default

shrinkOut

@Stable fun shrinkOut(
    shrinkTowards: Alignment = Alignment.BottomEnd,
    targetSize: (fullSize: IntSize) -> IntSize = { IntSize(0, 0) },
    animSpec: AnimationSpec<IntSize> = spring(),
    clip: Boolean = true
): ExitTransition

This shrinks the clip bounds of the disappearing content from the full size to the size returned from targetSize. shrinkTowards controls the direction of the bounds shrink animation. By default, the clip bounds animates from full size to IntSize(0, 0), shrinking towards the the bottom right corner (or bottom left corner in RTL layouts) of the content.

Note: shrinkOut animates the bounds of the content. This bounds change will also result in the animation of other layouts that are dependent on this size.

targetSize is a lambda that takes the full size of the content and returns a target size of the bounds of the content. This allows not only absolute size, but also a target size that is proportional to the content size.

clip defines whether the content outside of the animated bounds should be clipped. By default, clip is set to true, which only shows content in the animated bounds.

For shrinking only horizontally or vertically, consider shrinkHorizontally, shrinkVertically.

import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.core.tween
import androidx.compose.animation.expandIn
import androidx.compose.animation.shrinkOut
import androidx.compose.foundation.Text
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.unit.IntSize

var visible by remember { mutableStateOf(true) }

AnimatedVisibility(
    visible,
    enter = expandIn(
        // Overwrites the corner of the content that is first revealed
        expandFrom = Alignment.BottomStart,
        // Overwrites the initial size to 50 pixels by 50 pixels
        initialSize = { IntSize(50, 50) },
        // Overwrites the default spring animation with tween
        animSpec = tween(100, easing = LinearOutSlowInEasing)
    ),
    exit = shrinkOut(
        // Overwrites the area of the content that the shrink animation will end on. The
        // following parameters will shrink the content's clip bounds from the full size of the
        // content to 1/10 of the width and 1/5 of the height. The shrinking clip bounds will
        // always be aligned to the CenterStart of the full-content bounds.
        shrinkTowards = Alignment.CenterStart,
        // Overwrites the target size of the shrinking animation.
        targetSize = { fullSize -> IntSize(fullSize.width / 10, fullSize.height / 5) },
        animSpec = tween(100, easing = FastOutSlowInEasing)
    )
) {
    // Content that needs to appear/disappear goes here:
    Text("Content to appear/disappear", Modifier.fillMaxWidth().height(200.dp))
}
Parameters
shrinkTowards: Alignment = Alignment.BottomEnd the ending point of the shrinking bounds, Alignment.BottomEnd by default.
targetSize: (fullSize: IntSize) -> IntSize = { IntSize(0, 0) } returns the end size of the shrinking bounds, IntSize(0, 0) by default.
animSpec: AnimationSpec<IntSize> = spring() the animation used for the shrinking animation, spring by default.
clip: Boolean = true whether the content outside of the animated bounds should be clipped, true by default

shrinkVertically

@Stable fun shrinkVertically(
    shrinkTowards: Alignment.Vertical = Alignment.Bottom,
    targetHeight: (fullHeight: Int) -> Int = { 0 },
    animSpec: AnimationSpec<IntSize> = spring(),
    clip: Boolean = true
): ExitTransition

This shrinks the clip bounds of the disappearing content vertically, from the full height to the height returned from targetHeight. shrinkTowards controls the direction of the bounds shrink animation. By default, the clip bounds animates from full height to 0, shrinking towards the the bottom of the content.

Note: shrinkVertically animates the bounds of the content. This bounds change will also result in the animation of other layouts that are dependent on this size.

targetHeight is a lambda that takes the full height of the content and returns a target height of the content. This allows not only absolute height, but also a target height that is proportional to the content height.

clip defines whether the content outside of the animated bounds should be clipped. By default, clip is set to true, which only shows content in the animated bounds.

import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.core.tween
import androidx.compose.animation.expandVertically
import androidx.compose.animation.shrinkVertically
import androidx.compose.foundation.Text
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember

var visible by remember { mutableStateOf(true) }

AnimatedVisibility(
    visible,
    // Sets the initial height of the content to 20, revealing only the top of the content at
    // the beginning of the expanding animation.
    enter = expandVertically(
        expandFrom = Alignment.Top,
        initialHeight = { 20 }
    ),
    // Shrinks the content to half of its full height via an animation.
    exit = shrinkVertically(
        targetHeight = { fullHeight -> fullHeight / 2 },
        animSpec = tween()
    )
) {
    // Content that needs to appear/disappear goes here:
    Text("Content to appear/disappear", Modifier.fillMaxWidth().height(200.dp))
}
Parameters
shrinkTowards: Alignment.Vertical = Alignment.Bottom the ending point of the shrinking bounds, Alignment.Bottom by default.
targetHeight: (fullHeight: Int) -> Int = { 0 } returns the end height of the shrinking bounds, 0 by default.
animSpec: AnimationSpec<IntSize> = spring() the animation used for the shrinking animation, spring by default.
clip: Boolean = true whether the content outside of the animated bounds should be clipped, true by default

slideIn

@Stable fun slideIn(
    initialOffset: (fullSize: IntSize) -> IntOffset,
    animSpec: AnimationSpec<IntOffset> = spring()
): EnterTransition

This slides in the content of the transition, from a starting offset defined in initialOffset to IntOffset(0, 0). The direction of the slide can be controlled by configuring the initialOffset. A positive x value means sliding from right to left, whereas a negative x value will slide the content to the right. Similarly positive and negative y values correspond to sliding up and down, respectively.

If the sliding is only desired horizontally or vertically, instead of along both axis, consider using slideInHorizontally or slideInVertically.

initialOffset is a lambda that takes the full size of the content and returns an offset. This allows the offset to be defined proportional to the full size, or as an absolute value.

import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.core.tween
import androidx.compose.animation.slideIn
import androidx.compose.animation.slideOut
import androidx.compose.foundation.Text
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.unit.IntOffset

var visible by remember { mutableStateOf(true) }
AnimatedVisibility(
    visible,
    enter = slideIn(
        // Specifies the starting offset of the slide-in to be 1/4 of the width to the right,
        // 100 (pixels) below the content position, which results in a simultaneous slide up
        // and slide left.
        { fullSize -> IntOffset(fullSize.width / 4, 100) },
        tween(100, easing = LinearOutSlowInEasing)
    ),
    exit = slideOut(
        // The offset can be entirely independent of the size of the content. This specifies
        // a target offset 180 pixels to the left of the content, and 50 pixels below. This will
        // produce a slide-left combined with a slide-down.
        { IntOffset(-180, 50) },
        tween(100, easing = FastOutSlowInEasing)
    )
) {
    // Content that needs to appear/disappear goes here:
    Text("Content to appear/disappear", Modifier.fillMaxWidth().height(200.dp))
}
Parameters
initialOffset: (fullSize: IntSize) -> IntOffset a lambda that takes the full size of the content and returns the initial offset for the slide-in
animSpec: AnimationSpec<IntOffset> = spring() the animation used for the slide-in, spring by default.

slideInHorizontally

@Stable fun slideInHorizontally(
    initialOffsetX: (fullWidth: Int) -> Int = { -it / 2 },
    animSpec: AnimationSpec<IntOffset> = spring()
): EnterTransition

This slides in the content horizontally, from a starting offset defined in initialOffsetX to 0. The direction of the slide can be controlled by configuring the initialOffsetX. A positive value means sliding from right to left, whereas a negative value would slide the content from left to right.

initialOffsetX is a lambda that takes the full width of the content and returns an offset. This allows the starting offset to be defined proportional to the full size, or as an absolute value. It defaults to return half of negative width, which would offset the content to the left by half of its width, and slide towards the right.

import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.core.spring
import androidx.compose.animation.core.tween
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.animation.slideInHorizontally
import androidx.compose.animation.slideOutHorizontally
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember

var visible by remember { mutableStateOf(true) }
AnimatedVisibility(
    visible = visible,
    enter = slideInHorizontally(
        // Offsets the content by 1/3 of its width to the left, and slide towards right
        initialOffsetX = { fullWidth -> -fullWidth / 3 },
        // Overwrites the default animation with tween for this slide animation.
        animSpec = tween(durationMillis = 200)
    ) + fadeIn(
        // Overwrites the default animation with tween
        animSpec = tween(durationMillis = 200)
    ),
    exit = slideOutHorizontally(
        // Overwrites the ending position of the slide-out to 200 (pixels) to the right
        targetOffsetX = { 200 },
        animSpec = spring(stiffness = Spring.StiffnessHigh)
    ) + fadeOut()
) {
    // Content that needs to appear/disappear goes here:
    Box(Modifier.fillMaxWidth().height(200.dp)) {}
}
Parameters
initialOffsetX: (fullWidth: Int) -> Int = { -it / 2 } a lambda that takes the full width of the content and returns the initial offset for the slide-in, by default it returns -fullWidth/2
animSpec: AnimationSpec<IntOffset> = spring() the animation used for the slide-in, spring by default.

slideInVertically

@Stable fun slideInVertically(
    initialOffsetY: (fullHeight: Int) -> Int = { -it / 2 },
    animSpec: AnimationSpec<IntOffset> = spring()
): EnterTransition

This slides in the content vertically, from a starting offset defined in initialOffsetY to 0. The direction of the slide can be controlled by configuring the initialOffsetY. A positive initial offset means sliding up, whereas a negative value would slide the content down.

initialOffsetY is a lambda that takes the full Height of the content and returns an offset. This allows the starting offset to be defined proportional to the full height, or as an absolute value. It defaults to return half of negative height, which would offset the content up by half of its Height, and slide down.

import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.expandVertically
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.animation.shrinkVertically
import androidx.compose.animation.slideInVertically
import androidx.compose.animation.slideOutVertically
import androidx.compose.foundation.Text
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember

var visible by remember { mutableStateOf(true) }
AnimatedVisibility(
    visible = visible,
    enter = slideInVertically(
        // Start the slide from 40 (pixels) above where the content is supposed to go, to
        // produce a parallax effect
        initialOffsetY = { -40 }
    ) + expandVertically(
        expandFrom = Alignment.Top
    ) + fadeIn(initialAlpha = 0.3f),
    exit = slideOutVertically() + shrinkVertically() + fadeOut()
) {
    // Content that needs to appear/disappear goes here:
    Text("Content to appear/disappear", Modifier.fillMaxWidth().height(200.dp))
}
Parameters
initialOffsetY: (fullHeight: Int) -> Int = { -it / 2 } a lambda that takes the full Height of the content and returns the initial offset for the slide-in, by default it returns -fullHeight/2
animSpec: AnimationSpec<IntOffset> = spring() the animation used for the slide-in, spring by default.

slideOut

@Stable fun slideOut(
    targetOffset: (fullSize: IntSize) -> IntOffset,
    animSpec: AnimationSpec<IntOffset> = spring()
): ExitTransition

This slides out the content of the transition, from an offset of IntOffset(0, 0) to the target offset defined in targetOffset. The direction of the slide can be controlled by configuring the targetOffset. A positive x value means sliding from left to right, whereas a negative x value would slide the content from right to left. Similarly, positive and negative y values correspond to sliding down and up, respectively.

If the sliding is only desired horizontally or vertically, instead of along both axis, consider using slideOutHorizontally or slideOutVertically.

targetOffset is a lambda that takes the full size of the content and returns an offset. This allows the offset to be defined proportional to the full size, or as an absolute value.

import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.core.tween
import androidx.compose.animation.slideIn
import androidx.compose.animation.slideOut
import androidx.compose.foundation.Text
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.unit.IntOffset

var visible by remember { mutableStateOf(true) }
AnimatedVisibility(
    visible,
    enter = slideIn(
        // Specifies the starting offset of the slide-in to be 1/4 of the width to the right,
        // 100 (pixels) below the content position, which results in a simultaneous slide up
        // and slide left.
        { fullSize -> IntOffset(fullSize.width / 4, 100) },
        tween(100, easing = LinearOutSlowInEasing)
    ),
    exit = slideOut(
        // The offset can be entirely independent of the size of the content. This specifies
        // a target offset 180 pixels to the left of the content, and 50 pixels below. This will
        // produce a slide-left combined with a slide-down.
        { IntOffset(-180, 50) },
        tween(100, easing = FastOutSlowInEasing)
    )
) {
    // Content that needs to appear/disappear goes here:
    Text("Content to appear/disappear", Modifier.fillMaxWidth().height(200.dp))
}
Parameters
targetOffset: (fullSize: IntSize) -> IntOffset a lambda that takes the full size of the content and returns the target offset for the slide-out
animSpec: AnimationSpec<IntOffset> = spring() the animation used for the slide-out, spring by default.

slideOutHorizontally

@Stable fun slideOutHorizontally(
    targetOffsetX: (fullWidth: Int) -> Int = { -it / 2 },
    animSpec: AnimationSpec<IntOffset> = spring()
): ExitTransition

This slides out the content horizontally, from 0 to a target offset defined in targetOffsetX. The direction of the slide can be controlled by configuring the targetOffsetX. A positive value means sliding to the right, whereas a negative value would slide the content towards the left.

targetOffsetX is a lambda that takes the full width of the content and returns an offset. This allows the target offset to be defined proportional to the full size, or as an absolute value. It defaults to return half of negaive width, which would slide the content to the left by half of its width.

import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.core.spring
import androidx.compose.animation.core.tween
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.animation.slideInHorizontally
import androidx.compose.animation.slideOutHorizontally
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember

var visible by remember { mutableStateOf(true) }
AnimatedVisibility(
    visible = visible,
    enter = slideInHorizontally(
        // Offsets the content by 1/3 of its width to the left, and slide towards right
        initialOffsetX = { fullWidth -> -fullWidth / 3 },
        // Overwrites the default animation with tween for this slide animation.
        animSpec = tween(durationMillis = 200)
    ) + fadeIn(
        // Overwrites the default animation with tween
        animSpec = tween(durationMillis = 200)
    ),
    exit = slideOutHorizontally(
        // Overwrites the ending position of the slide-out to 200 (pixels) to the right
        targetOffsetX = { 200 },
        animSpec = spring(stiffness = Spring.StiffnessHigh)
    ) + fadeOut()
) {
    // Content that needs to appear/disappear goes here:
    Box(Modifier.fillMaxWidth().height(200.dp)) {}
}
Parameters
targetOffsetX: (fullWidth: Int) -> Int = { -it / 2 } a lambda that takes the full width of the content and returns the initial offset for the slide-in, by default it returns fullWidth/2
animSpec: AnimationSpec<IntOffset> = spring() the animation used for the slide-out, spring by default.

slideOutVertically

@Stable fun slideOutVertically(
    targetOffsetY: (fullHeight: Int) -> Int = { -it / 2 },
    animSpec: AnimationSpec<IntOffset> = spring()
): ExitTransition

This slides out the content vertically, from 0 to a target offset defined in targetOffsetY. The direction of the slide-out can be controlled by configuring the targetOffsetY. A positive target offset means sliding down, whereas a negative value would slide the content up.

targetOffsetY is a lambda that takes the full Height of the content and returns an offset. This allows the target offset to be defined proportional to the full height, or as an absolute value. It defaults to return half of the negative height, which would slide the content up by half of its Height.

Parameters
targetOffsetY: (fullHeight: Int) -> Int = { -it / 2 } a lambda that takes the full Height of the content and returns the target offset for the slide-out, by default it returns fullHeight/2
animSpec: AnimationSpec<IntOffset> = spring() the animation used for the slide-out, spring by default.

transition

@Composable fun <T> transition(
    definition: TransitionDefinition<T>,
    toState: T,
    clock: AnimationClockObservable = AnimationClockAmbient.current,
    initState: T = toState,
    label: String? = null,
    onStateChangeFinished: (T) -> Unit = null
): TransitionState

transition composable creates a state-based transition using the animation configuration defined in TransitionDefinition. This can be especially useful when animating multiple values from a predefined set of values to another. For animating a single value, consider using animatedValue, animatedFloat, animatedColor or the more light-weight animate APIs.

transition starts a new animation or changes the on-going animation when the toState parameter is changed to a different value. It dutifully ensures that the animation will head towards new toState regardless of what state (or in-between state) it’s currently in: If the transition is not currently animating, having a new toState value will start a new animation, otherwise the in-flight animation will correct course and animate towards the new toState based on the interruption handling logic.

transition takes a transition definition, a target state and child composables. These child composables will be receiving a TransitionState object as an argument, which captures all the current values of the animation. Child composables should read the animation values from the TransitionState object, and apply the value wherever necessary.

import androidx.compose.animation.ColorPropKey
import androidx.compose.animation.DpPropKey
import androidx.compose.animation.core.transitionDefinition
import androidx.compose.animation.transition
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.preferredSize

val colorKey = ColorPropKey()
val widthKey = DpPropKey()
val heightKey = DpPropKey()

val definition = transitionDefinition<State> {
    state(State.First) {
        this[colorKey] = Color.Red
        this[widthKey] = 200.dp
        this[heightKey] = 400.dp
    }
    state(State.Second) {
        this[colorKey] = Color.Green
        this[widthKey] = 300.dp
        this[heightKey] = 300.dp
    }
}

@Composable
fun TransitionBasedColoredRect() {
    // This puts the transition in State.First. Any subsequent state change will trigger a
    // transition animation, as defined in the transition definition.
    val state = transition(definition = definition, toState = State.First)
    Box(
        Modifier
            .preferredSize(state[widthKey], state[heightKey])
            .background(color = state[colorKey])
    )
}

@Composable
fun ColorRectWithInitState() {
    // This starts the transition going from State.First to State.Second when this composable
    // gets composed for the first time.
    val state = transition(
        definition = definition, initState = State.First, toState = State.Second
    )
    Box(
        Modifier
            .preferredSize(state[widthKey], state[heightKey])
            .background(state[colorKey])
    )
}
Parameters
definition: TransitionDefinition<T> Transition definition that defines states and transitions
toState: T New state to transition to
clock: AnimationClockObservable = AnimationClockAmbient.current Optional animation clock that pulses animations when time changes. By default, the system uses a choreographer based clock read from the AnimationClockAmbient. A custom implementation of the AnimationClockObservable (such as a androidx.compose.animation.core.ManualAnimationClock) can be supplied here if there’s a need to manually control the clock (for example in tests).
initState: T = toState Optional initial state for the transition. When undefined, the initial state will be set to the first toState seen in the transition.
label: String? = null Optional label for distinguishing different transitions in Android Studio.
onStateChangeFinished: (T) -> Unit = null An optional listener to get notified when state change animation has completed
Return
a TransitionState instance, from which the animation values can be read

Top-level properties

BoundsToVectorConverter

val BoundsToVectorConverter: TwoWayConverter<Bounds, AnimationVector4D>

Deprecated.

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

ColorToVectorConverter

val ColorToVectorConverter: (colorSpace: ColorSpace) -> TwoWayConverter<Color, AnimationVector4D>

Deprecated.

A lambda that takes a ColorSpace and returns a converter that can both convert a Color to a AnimationVector4D, and convert a AnimationVector4D) back to a Color in the given ColorSpace.

DpToVectorConverter

val DpToVectorConverter: TwoWayConverter<Dp, AnimationVector1D>

Deprecated.

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

IntPxPositionToVectorConverter

val IntPxPositionToVectorConverter: TwoWayConverter<IntOffset, AnimationVector2D>

Deprecated.

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

IntSizeToVectorConverter

val IntSizeToVectorConverter: TwoWayConverter<IntSize, AnimationVector2D>

Deprecated.

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

OffsetToVectorConverter

val OffsetToVectorConverter: TwoWayConverter<Offset, AnimationVector2D>

Deprecated.

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

PositionToVectorConverter

val PositionToVectorConverter: TwoWayConverter<Position, AnimationVector2D>

Deprecated.

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

PxBoundsToVectorConverter

val PxBoundsToVectorConverter: TwoWayConverter<PxBounds, AnimationVector4D>

Deprecated.

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

RectToVectorConverter

val RectToVectorConverter: TwoWayConverter<Rect, AnimationVector4D>

Deprecated.

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

SizeToVectorConverter

val SizeToVectorConverter: TwoWayConverter<Size, AnimationVector2D>

Deprecated.

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

Extension functions

AnimatedVisibility

@Composable fun RowScope.AnimatedVisibility(
    visible: Boolean,
    modifier: Modifier = Modifier,
    enter: EnterTransition = fadeIn() + expandHorizontally(),
    exit: ExitTransition = fadeOut() + shrinkHorizontally(),
    initiallyVisible: Boolean = visible,
    content: () -> Unit
): Unit

AnimatedVisibility composable animates the appearance and disappearance of its content, as visible value changes. Different EnterTransitions and ExitTransitions can be defined in enter and exit for the appearance and disappearance animation. There are 3 types of EnterTransition and ExitTransition: Fade, Expand/Shrink and Slide. The enter transitions and exit transitions can be combined using +. The order of the combination does not matter, as the transition animations will start simultaneously. See EnterTransition and ExitTransition for details on the three types of transition. Here's an example of using RowScope.AnimatedVisibility in a Row:

import androidx.compose.animation.AnimatedVisibility
import androidx.compose.foundation.Icon
import androidx.compose.foundation.Text
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.material.FloatingActionButton
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember

var expanded by remember { mutableStateOf(true) }
FloatingActionButton(
    onClick = { expanded = !expanded },
    modifier = with(ColumnScope) { Modifier.align(Alignment.CenterHorizontally) }
) {
    Row(Modifier.padding(start = 12.dp, end = 12.dp)) {
        Icon(Icons.Default.Favorite, Modifier.align(Alignment.CenterVertically))
        AnimatedVisibility(
            expanded,
            modifier = Modifier.align(Alignment.CenterVertically)
        ) {
            Text(modifier = Modifier.padding(start = 12.dp), text = "Favorite")
        }
    }
}
Spacer(Modifier.height(20.dp))

This composable function creates a custom Layout for its content. The size of the custom layout is determined by the largest width and largest height of the children. All children will be arranged in a box (aligned to the top start of the Layout).

Note: Once the exit transition is finished, the content composable will be skipped (i.e. the content will be removed from the tree, and disposed).

By default, the enter transition will be a combination of fading in and expanding the content horizontally. The end of the content will be the leading edge as the content expands to its full width. And the exit transition will be shrinking the content with the end of the content being the leading edge while fading out. The expanding and shrinking will likely also animate the parent and siblings in the row since they rely on the size of appearing/disappearing content.

initiallyVisible defaults to the same value as visible. This means when the AnimatedVisibility is first added to the tree, there is no appearing animation. If it is desired to show an appearing animation for the first appearance of the content, initiallyVisible can be set to false and visible to true.

Parameters
visible: Boolean defines whether the content should be visible
modifier: Modifier = Modifier modifier for the Layout created to contain the content
enter: EnterTransition = fadeIn() + expandHorizontally() EnterTransitions used for the appearing animation, fading in while expanding horizontally by default
exit: ExitTransition = fadeOut() + shrinkHorizontally() ExitTransition used for the disappearing animation, fading out while shrinking horizontally by default
initiallyVisible: Boolean = visible controls whether the first appearance should be animated, defaulting to match visible (i.e. not animating the first appearance)

AnimatedVisibility

@Composable fun ColumnScope.AnimatedVisibility(
    visible: Boolean,
    modifier: Modifier = Modifier,
    enter: EnterTransition = fadeIn() + expandVertically(),
    exit: ExitTransition = fadeOut() + shrinkVertically(),
    initiallyVisible: Boolean = visible,
    content: () -> Unit
): Unit

AnimatedVisibility composable animates the appearance and disappearance of its content, as visible value changes. Different EnterTransitions and ExitTransitions can be defined in enter and exit for the appearance and disappearance animation. There are 3 types of EnterTransition and ExitTransition: Fade, Expand/Shrink and Slide. The enter transitions and exit transitions can be combined using +. The order of the combination does not matter, as the transition animations will start simultaneously. See EnterTransition and ExitTransition for details on the three types of transition. Here's an example of using ColumnScope.AnimatedVisibility in a Column:

import androidx.compose.animation.AnimatedVisibility
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember

var itemIndex by remember { mutableStateOf(0) }
val colors = listOf(Color.Red, Color.Green, Color.Blue)
Column(
    Modifier.fillMaxWidth().clickable {
        itemIndex = (itemIndex + 1) % colors.size
    }
) {
    colors.forEachIndexed { i, color ->
        // By default ColumnScope.AnimatedVisibility expands and shrinks new content while
        // fading.
        AnimatedVisibility(i <= itemIndex) {
            Box(Modifier.height(40.dp).fillMaxWidth().background(color))
        }
    }
}

This composable function creates a custom Layout for its content. The size of the custom layout is determined by the largest width and largest height of the children. All children will be arranged in a box (aligned to the top start of the Layout).

Note: Once the exit transition is finished, the content composable will be skipped (i.e. the content will be removed from the tree, and disposed).

By default, the enter transition will be a combination of fading in and expanding the content vertically in the Column. The bottom of the content will be the leading edge as the content expands to its full height. And the exit transition will be shrinking the content with the bottom of the content being the leading edge while fading out. The expanding and shrinking will likely also animate the parent and siblings in the column since they rely on the size of appearing/disappearing content.

initiallyVisible defaults to the same value as visible. This means when the AnimatedVisibility is first added to the tree, there is no appearing animation. If it is desired to show an appearing animation for the first appearance of the content, initiallyVisible can be set to false and visible to true.

Parameters
visible: Boolean defines whether the content should be visible
modifier: Modifier = Modifier modifier for the Layout created to contain the content
enter: EnterTransition = fadeIn() + expandVertically() EnterTransitions used for the appearing animation, fading in while expanding vertically by default
exit: ExitTransition = fadeOut() + shrinkVertically() ExitTransition used for the disappearing animation, fading out while shrinking vertically by default
initiallyVisible: Boolean = visible controls whether the first appearance should be animated, defaulting to match visible (i.e. not animating the first appearance)

animateContentSize

fun Modifier.animateContentSize(
    animSpec: AnimationSpec<IntSize> = spring(),
    clip: Boolean = true,
    endListener: (startSize: IntSize, endSize: IntSize) -> Unit = null
): Modifier

This modifier animates its own size when its child modifier (or the child composable if it is already at the tail of the chain) changes size. This allows the parent modifier to observe a smooth size change, resulting in an overall continuous visual change.

An AnimationSpec can be optionally specified for the size change animation. By default, SpringSpec will be used. Clipping defaults to true, such that the content outside of animated size will not be shown.

An optional endListener can be supplied to get notified when the size change animation is finished. Since the content size change can be dynamic in many cases, both start size and end size will be passed to the endListener. Note: if the animation is interrupted, the start size will be the size at the point of interruption. This is intended to help determine the direction of the size change (i.e. expand or collapse in x and y dimensions).

import androidx.compose.animation.animateContentSize
import androidx.compose.foundation.Text
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember

val shortText = "Hi"
val longText = "Very long text\nthat spans across\nmultiple lines"
var short by remember { mutableStateOf(true) }
Box(
    modifier = Modifier
        .background(
            Color.Blue,
            RoundedCornerShape(15.dp)
        )
        .clickable { short = !short }
        .padding(20.dp)
        .wrapContentSize()
        .animateContentSize()
) {
    Text(
        if (short) {
            shortText
        } else {
            longText
        },
        style = AmbientTextStyle.current.copy(color = Color.White)
    )
}
Parameters
animSpec: AnimationSpec<IntSize> = spring() the animation that will be used to animate size change
clip: Boolean = true whether content outside of animated size should be clipped
endListener: (startSize: IntSize, endSize: IntSize) -> Unit = null optional listener to be called when the content change animation is completed.

asDisposableClock

@Composable fun AnimationClockObservable.asDisposableClock(): DisposableAnimationClock

Return a new AnimationClockObservable wrapping this one that will auto-unsubscribe all AnimationClockObservers when this call leaves the composition, preventing clock subscriptions from persisting beyond the composition lifecycle.

If you are creating an animation object during composition that will subscribe to an AnimationClockObservable or otherwise hold a long-lived reference to one to subscribe to later, create that object with a clock returned by this method.