---
title: "updateTransition"
description: "This sets up a [Transition], and updates it with the target provided by [targetState]. When
[targetState] changes, [Transition] will run all of its child animations towards their target
values specified for the new [targetState]. Child animations can be dynamically added using
[Transition.animateFloat], [animateColor][ androidx.compose.animation.animateColor],
[Transition.animateValue], etc.

[label] is used to differentiate different transitions in Android Studio.

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

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


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

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


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


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

`label` is used to differentiate different transitions in Android Studio.

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

#### Returns

| | |
| --- | --- |
|  | a `Transition` object, to which animations can be added. |




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


> **Deprecated** Use rememberTransition() instead

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


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

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

Compared to the `rememberTransition` variant 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,
            )
        }
    }
}
```
### GestureAnimationSample
```kotlin
@Composable
fun GestureAnimationSample() {
    // enum class ComponentState { Pressed, Released }
    var useRed by remember { mutableStateOf(false) }
    var toState by remember { mutableStateOf(ComponentState.Released) }
    val modifier =
        Modifier.pointerInput(Unit) {
            detectTapGestures(
                onPress = {
                    toState = ComponentState.Pressed
                    tryAwaitRelease()
                    toState = ComponentState.Released
                }
            )
        }
    // Defines a transition of `ComponentState`, and updates the transition when the provided
    // [targetState] changes. The transition will run all of the child animations towards the new
    // [targetState] in response to the [targetState] change.
    val transition: Transition<ComponentState> = updateTransition(targetState = toState)
    // Defines a float animation as a child animation the transition. The current animation value
    // can be read from the returned State<Float>.
    val scale: Float by
        transition.animateFloat(
            // Defines a transition spec that uses the same low-stiffness spring for *all*
            // transitions of this float, no matter what the target is.
            transitionSpec = { spring(stiffness = 50f) }
        ) { state ->
            // This code block declares a mapping from state to value.
            if (state == ComponentState.Pressed) 3f else 1f
        }
    // Defines a color animation as a child animation of the transition.
    val color: Color by
        transition.animateColor(
            transitionSpec = {
                when {
                    ComponentState.Pressed isTransitioningTo ComponentState.Released ->
                        // Uses spring for the transition going from pressed to released
                        spring(stiffness = 50f)
                    else ->
                        // Uses tween for all the other transitions. (In this case there is
                        // only one other transition. i.e. released -> pressed.)
                        tween(durationMillis = 500)
                }
            }
        ) { state ->
            when (state) {
                // Similar to the float animation, we need to declare the target values
                // for each state. In this code block we can access theme colors.
                ComponentState.Pressed -> MaterialTheme.colors.primary
                // We can also have the target value depend on other mutableStates,
                // such as `useRed` here. Whenever the target value changes, transition
                // will automatically animate to the new value even if it has already
                // arrived at its target state.
                ComponentState.Released -> if (useRed) Color.Red else MaterialTheme.colors.secondary
            }
        }
    Column {
        Button(
            modifier = Modifier.padding(10.dp).align(Alignment.CenterHorizontally),
            onClick = { useRed = !useRed },
        ) {
            Text("Change Color")
        }
        Box(
            modifier
                .fillMaxSize()
                .wrapContentSize(Alignment.Center)
                .size((100 * scale).dp)
                .background(color)
        )
    }
}
```
### 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,
        ) {}
    }
}
```

