---
title: "rememberTransition"
description: "Creates a [Transition] and puts it in the [currentState][TransitionState.currentState] of the
provided [transitionState]. If the [TransitionState.targetState] changes, the [Transition] will
change where it will animate to.

__Remember__: The provided [transitionState] needs to be [remember]ed.

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


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

<div class='type'>Composable Function</div>


<a id='references'></a>

<div class='sourceset sourceset-common'>Common</div>


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


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

__Remember__: The provided `transitionState` needs to be `remember`ed.

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


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




## Code Examples
### DoubleTapToLikeSample
```kotlin
@Composable
fun DoubleTapToLikeSample() {
    // enum class LikedStates { Initial, Liked, Disappeared }
    @Composable
    fun doubleTapToLike() {
        // Creates a transition state that starts in [Disappeared] State
        var transitionState by remember {
            mutableStateOf(MutableTransitionState(LikedStates.Disappeared))
        }
        Box(
            Modifier.fillMaxSize().pointerInput(Unit) {
                detectTapGestures(
                    onDoubleTap = {
                        // This creates a new `MutableTransitionState` object. When a new
                        // `MutableTransitionState` object gets passed to `updateTransition`, a
                        // new transition will be created. All existing values, velocities will
                        // be lost as a result. Hence, in most cases, this is not recommended.
                        // The exception is when it's more important to respond immediately to
                        // user interaction than preserving continuity.
                        transitionState = MutableTransitionState(LikedStates.Initial)
                    }
                )
            }
        ) {
            // This ensures sequential states: Initial -> Liked -> Disappeared
            if (transitionState.currentState == LikedStates.Initial) {
                transitionState.targetState = LikedStates.Liked
            } else if (transitionState.currentState == LikedStates.Liked) {
                // currentState will be updated to targetState when the transition is finished, so
                // it can be used as a signal to start the next transition.
                transitionState.targetState = LikedStates.Disappeared
            }
            // Creates a transition using the TransitionState object that gets recreated at each
            // double tap.
            val transition = rememberTransition(transitionState)
            // Creates an alpha animation, as a part of the transition.
            val alpha by
                transition.animateFloat(
                    transitionSpec = {
                        when {
                            // Uses different animation specs for transitioning from/to different
                            // states
                            LikedStates.Initial isTransitioningTo LikedStates.Liked ->
                                keyframes {
                                    durationMillis = 500
                                    0f at 0 // optional
                                    0.5f at 100
                                    1f at 225 // optional
                                }
                            LikedStates.Liked isTransitioningTo LikedStates.Disappeared ->
                                tween(durationMillis = 200)
                            else -> snap()
                        }
                    }
                ) {
                    if (it == LikedStates.Liked) 1f else 0f
                }
            // Creates a scale animation, as a part of the transition
            val scale by
                transition.animateFloat(
                    transitionSpec = {
                        when {
                            // Uses different animation specs for transitioning from/to different
                            // states
                            LikedStates.Initial isTransitioningTo LikedStates.Liked ->
                                spring(dampingRatio = Spring.DampingRatioHighBouncy)
                            LikedStates.Liked isTransitioningTo LikedStates.Disappeared ->
                                tween(200)
                            else -> snap()
                        }
                    }
                ) {
                    when (it) {
                        LikedStates.Initial -> 0f
                        LikedStates.Liked -> 4f
                        LikedStates.Disappeared -> 2f
                    }
                }
            Icon(
                Icons.Filled.Favorite,
                "Like",
                Modifier.align(Alignment.Center)
                    .graphicsLayer(alpha = alpha, scaleX = scale, scaleY = scale),
                tint = Color.Red,
            )
        }
    }
}
```
### InitialStateSample
```kotlin
@OptIn(ExperimentalTransitionApi::class)
fun InitialStateSample() {
    // This composable enters the composition with a custom enter transition. This is achieved by
    // defining a different initialState than the first target state using `MutableTransitionState`
    @Composable
    fun PoppingInCard() {
        // Creates a transition state with an initial state where visible = false
        val visibleState = remember { MutableTransitionState(false) }
        // Sets the target state of the transition state to true. As it's different than the initial
        // state, a transition from not visible to visible will be triggered.
        visibleState.targetState = true
        // Creates a transition with the transition state created above.
        val transition = rememberTransition(visibleState)
        // Adds a scale animation to the transition to scale the card up when transitioning in.
        val scale by
            transition.animateFloat(
                // Uses a custom spring for the transition.
                transitionSpec = { spring(dampingRatio = Spring.DampingRatioMediumBouncy) }
            ) { visible ->
                if (visible) 1f else 0.8f
            }
        // Adds an elevation animation that animates the dp value of the animation.
        val elevation by
            transition.animateDp(
                // Uses a tween animation
                transitionSpec = {
                    // Uses different animations for when animating from visible to not visible, and
                    // the other way around
                    if (false isTransitioningTo true) {
                        tween(1000)
                    } else {
                        spring()
                    }
                }
            ) { visible ->
                if (visible) 10.dp else 0.dp
            }
        Card(
            Modifier.graphicsLayer(scaleX = scale, scaleY = scale)
                .size(200.dp, 100.dp)
                .fillMaxWidth(),
            elevation = elevation,
        ) {}
    }
}
```

