SeekableTransitionState
public class SeekableTransitionState<S>(initialState: S) : TransitionState<S>()
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.
Functions
public suspend fun snapTo(targetState: S)
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.
public suspend fun seekTo(
@FloatRange(from = 0.0, to = 1.0) fraction: Float,
targetState: S = this.targetState,
)
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.
public suspend fun animateTo(
targetState: S = this.targetState,
animationSpec: FiniteAnimationSpec<Float>? = null,
)
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 | The state to animate towards. |
| animationSpec | If provided, is used to animate the animation fraction. If null, the transition is linearly traversed based on the duration of the transition. |
Companion Object
Properties
val ZeroVelocity = AnimationVector1D(0f)
val Target1 = AnimationVector1D(1f)
Code Examples
SeekingAnimationSample
@Composable
fun SeekingAnimationSample() {
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)
)
}
}
