# updateTransition

Common/All

## Functions summary

|---|---|---|
| `https://developer.android.com/reference/kotlin/androidx/compose/animation/core/Transition<T>` | `@https://developer.android.com/reference/kotlin/androidx/compose/runtime/Composable <T : https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-any/index.html?> https://developer.android.com/reference/kotlin/androidx/compose/animation/core/updateTransition.composable#updateTransition(kotlin.Any,kotlin.String)(targetState: T, label: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-string/index.html?)` This sets up a `https://developer.android.com/reference/kotlin/androidx/compose/animation/core/Transition`, and updates it with the target provided by `https://developer.android.com/reference/kotlin/androidx/compose/animation/core/package-summary#updateTransition(kotlin.Any,kotlin.String)`. | Cmn |
| `https://developer.android.com/reference/kotlin/androidx/compose/animation/core/Transition<T>` | `@https://developer.android.com/reference/kotlin/androidx/compose/runtime/Composable <T : https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-any/index.html?> [updateTransition](https://developer.android.com/reference/kotlin/androidx/compose/animation/core/updateTransition.composable#updateTransition(androidx.compose.animation.core.MutableTransitionState,kotlin.String))( transitionState: https://developer.android.com/reference/kotlin/androidx/compose/animation/core/MutableTransitionState<T>, label: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-string/index.html? )` **This function is deprecated.** Use rememberTransition() instead | Cmn |

## Functions

### updateTransition

Cmn Artifact: [androidx.compose.animation:animation-core](https://developer.android.com/jetpack/androidx/releases/compose-animation) [View Source](https://cs.android.com/search?q=file:androidx/compose/animation/core/Transition.kt+function:updateTransition) Added in [1.0.0](https://developer.android.com/jetpack/androidx/releases/compose-animation#1.0.0)

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

This sets up a `https://developer.android.com/reference/kotlin/androidx/compose/animation/core/Transition`, and updates it with the target provided by `https://developer.android.com/reference/kotlin/androidx/compose/animation/core/package-summary#updateTransition(kotlin.Any,kotlin.String)`. When `https://developer.android.com/reference/kotlin/androidx/compose/animation/core/package-summary#updateTransition(kotlin.Any,kotlin.String)` changes, `https://developer.android.com/reference/kotlin/androidx/compose/animation/core/Transition` will run all of its child animations towards their target values specified for the new `https://developer.android.com/reference/kotlin/androidx/compose/animation/core/package-summary#updateTransition(kotlin.Any,kotlin.String)`. Child animations can be dynamically added using `https://developer.android.com/reference/kotlin/androidx/compose/animation/core/animateFloat.composable#(androidx.compose.animation.core.Transition).animateFloat(kotlin.Function1,kotlin.String,kotlin.Function1)`, androidx.compose.animation.animateColor, `https://developer.android.com/reference/kotlin/androidx/compose/animation/core/animateValue.composable#(androidx.compose.animation.core.Transition).animateValue(androidx.compose.animation.core.TwoWayConverter,kotlin.Function1,kotlin.String,kotlin.Function1)`, etc.

`https://developer.android.com/reference/kotlin/androidx/compose/animation/core/package-summary#updateTransition(kotlin.Any,kotlin.String)` is used to differentiate different transitions in Android Studio.

**Note** : There is another `https://developer.android.com/reference/kotlin/androidx/compose/animation/core/rememberTransition.composable#rememberTransition(androidx.compose.animation.core.TransitionState,kotlin.String)` overload that accepts a `https://developer.android.com/reference/kotlin/androidx/compose/animation/core/MutableTransitionState`. The difference between the two is that the `https://developer.android.com/reference/kotlin/androidx/compose/animation/core/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.

```kotlin
import androidx.compose.animation.animateColor
import androidx.compose.animation.core.Transition
import androidx.compose.animation.core.animateFloat
import androidx.compose.animation.core.spring
import androidx.compose.animation.core.tween
import androidx.compose.animation.core.updateTransition
import androidx.compose.foundation.background
import androidx.compose.foundation.gestures.detectTapGestures
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.material.Button
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.scale
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.unit.dp

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

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

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

| Returns |
|---|---|
| `https://developer.android.com/reference/kotlin/androidx/compose/animation/core/Transition<T>` | a `https://developer.android.com/reference/kotlin/androidx/compose/animation/core/Transition` object, to which animations can be added. |

| See also |
|---|---|
| `https://developer.android.com/reference/kotlin/androidx/compose/animation/core/Transition` |   |
| `https://developer.android.com/reference/kotlin/androidx/compose/animation/core/animateFloat.composable#(androidx.compose.animation.core.Transition).animateFloat(kotlin.Function1,kotlin.String,kotlin.Function1)` |   |
| `https://developer.android.com/reference/kotlin/androidx/compose/animation/core/animateValue.composable#(androidx.compose.animation.core.Transition).animateValue(androidx.compose.animation.core.TwoWayConverter,kotlin.Function1,kotlin.String,kotlin.Function1)` |   |

### updateTransition

Cmn Artifact: [androidx.compose.animation:animation-core](https://developer.android.com/jetpack/androidx/releases/compose-animation) [View Source](https://cs.android.com/search?q=file:androidx/compose/animation/core/Transition.kt+function:updateTransition) Added in [1.0.0](https://developer.android.com/jetpack/androidx/releases/compose-animation#1.0.0) Deprecated in [1.7.0](https://developer.android.com/jetpack/androidx/releases/compose-animation#1.7.0)

```
@Composable
fun <T : Any?> [updateTransition](https://developer.android.com/reference/kotlin/androidx/compose/animation/core/updateTransition.composable#updateTransition(androidx.compose.animation.core.MutableTransitionState,kotlin.String))(
    transitionState: MutableTransitionState<T>,
    label: String? = null
): Transition<T>
```

> [!CAUTION]
> **This function is deprecated.**   
> Use rememberTransition() instead, use this instead:
>
> ```kotlin
> rememberTransition(transitionState, label)
> ```

Creates a `https://developer.android.com/reference/kotlin/androidx/compose/animation/core/Transition` and puts it in the `https://developer.android.com/reference/kotlin/androidx/compose/animation/core/MutableTransitionState#currentState()` of the provided `https://developer.android.com/reference/kotlin/androidx/compose/animation/core/package-summary#updateTransition(androidx.compose.animation.core.MutableTransitionState,kotlin.String)`. Whenever the `https://developer.android.com/reference/kotlin/androidx/compose/animation/core/MutableTransitionState#targetState()` of the `https://developer.android.com/reference/kotlin/androidx/compose/animation/core/package-summary#updateTransition(androidx.compose.animation.core.MutableTransitionState,kotlin.String)` changes, the `https://developer.android.com/reference/kotlin/androidx/compose/animation/core/Transition` will animate to the new target state.

**Remember** : The provided `https://developer.android.com/reference/kotlin/androidx/compose/animation/core/package-summary#updateTransition(androidx.compose.animation.core.MutableTransitionState,kotlin.String)` needs to be `https://developer.android.com/reference/kotlin/androidx/compose/runtime/remember.composable#remember(kotlin.Function0)`ed.

Compared to the `https://developer.android.com/reference/kotlin/androidx/compose/animation/core/rememberTransition.composable#rememberTransition(androidx.compose.animation.core.TransitionState,kotlin.String)` variant that takes a targetState, this function supports a different initial state than the first targetState. Here is an example:

```kotlin
import androidx.compose.animation.core.MutableTransitionState
import androidx.compose.animation.core.Spring
import androidx.compose.animation.core.Transition
import androidx.compose.animation.core.animateDp
import androidx.compose.animation.core.animateFloat
import androidx.compose.animation.core.rememberTransition
import androidx.compose.animation.core.spring
import androidx.compose.animation.core.tween
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.size
import androidx.compose.material.Card
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.scale
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.unit.dp

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

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

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

In most cases, it is recommended to reuse the same `https://developer.android.com/reference/kotlin/androidx/compose/animation/core/package-summary#updateTransition(androidx.compose.animation.core.MutableTransitionState,kotlin.String)` that is `https://developer.android.com/reference/kotlin/androidx/compose/runtime/remember.composable#remember(kotlin.Function0)`ed, such that `https://developer.android.com/reference/kotlin/androidx/compose/animation/core/Transition` preserves continuity when `https://developer.android.com/reference/kotlin/androidx/compose/animation/core/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 `https://developer.android.com/reference/kotlin/androidx/compose/animation/core/package-summary#updateTransition(androidx.compose.animation.core.MutableTransitionState,kotlin.String)`:

```kotlin
import androidx.compose.animation.core.MutableTransitionState
import androidx.compose.animation.core.Spring
import androidx.compose.animation.core.Transition
import androidx.compose.animation.core.animateFloat
import androidx.compose.animation.core.keyframes
import androidx.compose.animation.core.rememberTransition
import androidx.compose.animation.core.snap
import androidx.compose.animation.core.spring
import androidx.compose.animation.core.tween
import androidx.compose.animation.core.updateTransition
import androidx.compose.foundation.gestures.detectTapGestures
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material.Icon
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Favorite
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.scale
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.input.pointer.pointerInput

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

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

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

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

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