---
title: "Transition"
description: "[Transition] manages all the child animations on a state level. Child animations can be created
in a declarative way using [Transition.animateFloat], [Transition.animateValue],
[animateColor][androidx.compose.animation.animateColor] etc. When the [targetState] changes,
[Transition] will automatically start or adjust course for all its child animations to animate to
the new target values defined for each animation.

After arriving at [targetState], [Transition] will be triggered to run if any child animation
changes its target value (due to their dynamic target calculation logic, such as theme-dependent
values)."
type: "class"
---

<div class='type'>Class</div>


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

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


```kotlin
public class Transition<S>
internal constructor(
    private val transitionState: TransitionState<S>,
    @get:RestrictTo(RestrictTo.Scope.LIBRARY) public val parentTransition: Transition<*>?,
    public val label: String? = null,
)
```


`Transition` manages all the child animations on a state level. Child animations can be created
in a declarative way using `Transition.animateFloat`, `Transition.animateValue`,
`animateColor` etc. When the `targetState` changes,
`Transition` will automatically start or adjust course for all its child animations to animate to
the new target values defined for each animation.

After arriving at `targetState`, `Transition` will be triggered to run if any child animation
changes its target value (due to their dynamic target calculation logic, such as theme-dependent
values).


## Secondary Constructors

```kotlin
@PublishedApi
internal constructor(
    transitionState: TransitionState<S>,
    label: String? = null,
) : this(transitionState, null, label)
```

```kotlin
internal constructor(
    initialState: S,
    label: String?,
) : this(MutableTransitionState(initialState), null, label)
```

```kotlin
@PublishedApi
internal constructor(
    transitionState: MutableTransitionState<S>,
    label: String? = null,
) : this(transitionState as TransitionState<S>, null, label)
```

## Functions

```kotlin
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP_PREFIX)
    
    
    public fun setPlaytimeAfterInitialAndTargetStateEstablished(
        initialState: S,
        targetState: S,
        playTimeNanos: Long,
    )
```


This allows tools to set the transition (between initial and target state) to a specific
`playTimeNanos`.

Note: This function is intended for tooling use only.

__Caveat:__ Once `initialState` or `targetState` changes, it needs to take a whole
composition pass for all the animations and child transitions to recompose with the new
`initialState` and `targetState`. Subsequently all the animations will be updated to the
given play time.

__Caveat:__ This function puts `Transition` in a manual playtime setting mode. From then on
the `Transition` will not resume normal animation runs.



## Code Examples

### 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)
        )
    }
}
```

