SeekableTransitionState


A TransitionState that can manipulate the progress of the Transition by seeking with seekTo or animating with animateTo.

A SeekableTransitionState can only be used with one Transition instance. Once assigned, it cannot be reassigned to a different Transition instance.

import androidx.compose.animation.AnimatedContent import androidx.compose.animation.core.LinearEasing import androidx.compose.animation.core.SeekableTransitionState import androidx.compose.animation.core.Transition import androidx.compose.animation.core.animateFloat import androidx.compose.animation.core.rememberTransition import androidx.compose.animation.core.tween import androidx.compose.animation.fadeIn import androidx.compose.animation.fadeOut import androidx.compose.animation.togetherWith import androidx.compose.foundation.background import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row 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.foundation.layout.wrapContentWidth import androidx.compose.foundation.systemGestureExclusion import androidx.compose.material.Button import androidx.compose.material.Slider import androidx.compose.material.Text import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope 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.unit.dp Column {  val seekingState = remember { SeekableTransitionState(BoxSize.Small) }  val scope = rememberCoroutineScope()  Column {  Row {  Button(  onClick = { scope.launch { seekingState.animateTo(BoxSize.Small) } },  Modifier.wrapContentWidth().weight(1f),  ) {  Text("Animate Small")  }  Button(  onClick = { scope.launch { seekingState.seekTo(0f, BoxSize.Small) } },  Modifier.wrapContentWidth().weight(1f),  ) {  Text("Seek Small")  }  Button(  onClick = { scope.launch { seekingState.seekTo(0f, BoxSize.Medium) } },  Modifier.wrapContentWidth().weight(1f),  ) {  Text("Seek Medium")  }  Button(  onClick = { scope.launch { seekingState.seekTo(0f, BoxSize.Large) } },  Modifier.wrapContentWidth().weight(1f),  ) {  Text("Seek Large")  }  Button(  onClick = { scope.launch { seekingState.animateTo(BoxSize.Large) } },  Modifier.wrapContentWidth().weight(1f),  ) {  Text("Animate Large")  }  }  }  Slider(  value = seekingState.fraction,  modifier = Modifier.systemGestureExclusion().padding(10.dp),  onValueChange = { value -> scope.launch { seekingState.seekTo(fraction = value) } },  )  val transition = rememberTransition(seekingState)  val scale: Float by  transition.animateFloat(  transitionSpec = { tween(easing = LinearEasing) },  label = "Scale",  ) { state ->  when (state) {  BoxSize.Small -> 1f  BoxSize.Medium -> 2f  BoxSize.Large -> 3f  }  }  transition.AnimatedContent(  transitionSpec = {  fadeIn(tween(easing = LinearEasing)) togetherWith  fadeOut(tween(easing = LinearEasing))  }  ) { state ->  if (state == BoxSize.Large) {  Box(Modifier.size(50.dp).background(Color.Magenta))  } else {  Box(Modifier.size(50.dp))  }  }  Box(  Modifier.fillMaxSize()  .wrapContentSize(Alignment.Center)  .size(100.dp)  .graphicsLayer {  scaleX = scale  scaleY = scale  }  .background(Color.Blue)  ) }

Summary

Public constructors

<S : Any?> SeekableTransitionState(initialState: S)
Cmn

Public functions

suspend Unit
animateTo(targetState: S, animationSpec: FiniteAnimationSpec<Float>?)

Updates the current targetState to targetState and begins an animation to the new state.

Cmn
suspend Unit
seekTo(fraction: @FloatRange(from = 0.0, to = 1.0) Float, targetState: S)

Starts seeking the transition to targetState with fraction used to indicate the progress towards targetState.

Cmn
suspend Unit
snapTo(targetState: S)

Sets currentState and targetState to targetState and snaps all values to those at that state.

Cmn

Public properties

open S

Current state of the transition.

Cmn
Float

The progress of the transition from currentState to targetState as a fraction of the entire duration.

Cmn
open S

Target state of the transition.

Cmn

Public constructors

SeekableTransitionState

<S : Any?> SeekableTransitionState(initialState: S)

Public functions

animateTo

suspend fun animateTo(
    targetState: S = this.targetState,
    animationSpec: FiniteAnimationSpec<Float>? = null
): Unit

Updates the current targetState to targetState and begins an animation to the new state. If the current targetState is the same as targetState then the current transition animation is continued. If a previous transition was interrupted, currentState is changed to the former targetState and the start values are animated toward the former targetState.

Upon completion of the animation, currentState will be changed to targetState.

Parameters
targetState: S = this.targetState

The state to animate towards.

animationSpec: FiniteAnimationSpec<Float>? = null

If provided, is used to animate the animation fraction. If null, the transition is linearly traversed based on the duration of the transition.

seekTo

suspend fun seekTo(
    fraction: @FloatRange(from = 0.0, to = 1.0) Float,
    targetState: S = this.targetState
): Unit

Starts seeking the transition to targetState with fraction used to indicate the progress towards targetState. If the previous targetState was already targetState then seekTo only stops any current animation towards that state and snaps the fraction to the new value. Otherwise, the currentState is changed to the former targetState and targetState is changed to targetState and an animation is started, moving the start values towards the former targetState. This will return when the initial values have reached currentState and the fraction has been reached.

snapTo also allows the developer to change the state, but does not animate any values. Instead, it instantly moves all values to those at the new targetState.

import androidx.compose.animation.core.SeekableTransitionState import androidx.compose.animation.core.Transition import androidx.compose.animation.core.rememberTransition import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.padding import androidx.compose.foundation.systemGestureExclusion import androidx.compose.material.Slider import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp val seekingState = remember { SeekableTransitionState(BoxSize.Small) } LaunchedEffect(seekingState.targetState) { seekingState.seekTo(0f, BoxSize.Large) } val scope = rememberCoroutineScope() Slider(  value = seekingState.fraction,  modifier = Modifier.systemGestureExclusion().padding(10.dp),  onValueChange = { value -> scope.launch { seekingState.seekTo(fraction = value) } }, ) val transition = rememberTransition(seekingState) // use the transition
See also
animateTo

snapTo

suspend fun snapTo(targetState: S): Unit

Sets currentState and targetState to targetState and snaps all values to those at that state. The transition will not have any animations running after running snapTo.

This can have a similar effect as seekTo. However, seekTo moves the currentState to the former targetState and animates the initial values of the animations from the current values to those at currentState. seekTo also allows the developer to move the state between any fraction between currentState and targetState, while snapTo moves all state to targetState without any further seeking allowed.

import androidx.compose.animation.core.SeekableTransitionState import androidx.compose.animation.core.Transition import androidx.compose.animation.core.rememberTransition import androidx.compose.animation.core.snap import androidx.compose.foundation.layout.Box import androidx.compose.material.Button import androidx.compose.material.Text import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope val seekingState = remember { SeekableTransitionState(BoxSize.Small) } val scope = rememberCoroutineScope() Button(onClick = { scope.launch { seekingState.snapTo(BoxSize.Large) } }) {  Text("Snap to the Small state") } val transition = rememberTransition(seekingState) // use the transition
See also
animateTo

Public properties

currentState

open val currentState: S

Current state of the transition. If there is an active transition, currentState and targetState are different.

fraction

val fractionFloat

The progress of the transition from currentState to targetState as a fraction of the entire duration.

If targetState and currentState are the same, fraction will be 0.

targetState

open val targetState: S

Target state of the transition. If this is the same as currentState, no transition is active.