@ExperimentalMotionApi
@LayoutScopeMarker
class TransitionScope


Scope where Transition parameters are defined.

Here, you may define multiple KeyFrames for specific ConstrainedLayoutReferences, as well was enabling OnSwipe handling.

Summary

Public functions

ConstrainedLayoutReference

Creates one ConstrainedLayoutReference corresponding to the ConstraintLayout element with id.

Unit
keyAttributes(
    vararg targets: ConstrainedLayoutReference,
    keyAttributesContent: KeyAttributesScope.() -> Unit
)

Define KeyAttribute KeyFrames for the given targets.

Unit
keyCycles(
    vararg targets: ConstrainedLayoutReference,
    keyCyclesContent: KeyCyclesScope.() -> Unit
)

Define KeyCycle KeyFrames for the given targets.

Unit
keyPositions(
    vararg targets: ConstrainedLayoutReference,
    keyPositionsContent: KeyPositionsScope.() -> Unit
)

Define KeyPosition KeyFrames for the given targets.

Public properties

@FloatRange(from = -1.0, to = 1.0, fromInclusive = false, toInclusive = false) Float

Defines the maximum delay (in progress value) between a group of staggered widgets.

Arc

The default Arc shape for animated layout movement.

OnSwipe?

When not null, enables animating through the transition with touch input.

Public functions

createRefFor

Added in 1.1.0
fun createRefFor(id: Any): ConstrainedLayoutReference

Creates one ConstrainedLayoutReference corresponding to the ConstraintLayout element with id.

keyAttributes

fun keyAttributes(
    vararg targets: ConstrainedLayoutReference,
    keyAttributesContent: KeyAttributesScope.() -> Unit
): Unit

Define KeyAttribute KeyFrames for the given targets.

Set multiple KeyFrames with KeyAttributesScope.frame.

keyCycles

fun keyCycles(
    vararg targets: ConstrainedLayoutReference,
    keyCyclesContent: KeyCyclesScope.() -> Unit
): Unit

Define KeyCycle KeyFrames for the given targets.

Set multiple KeyFrames with KeyCyclesScope.frame.

keyPositions

fun keyPositions(
    vararg targets: ConstrainedLayoutReference,
    keyPositionsContent: KeyPositionsScope.() -> Unit
): Unit

Define KeyPosition KeyFrames for the given targets.

Set multiple KeyFrames with KeyPositionsScope.frame.

Public properties

maxStaggerDelay

Added in 1.1.0
var maxStaggerDelay: @FloatRange(from = -1.0, to = 1.0, fromInclusive = false, toInclusive = false) Float

Defines the maximum delay (in progress value) between a group of staggered widgets.

The amount of delay for each widget is decided based on its weight. Where the widget with the lowest weight will receive the full delay. A negative maxStaggerDelay value inverts this logic, so that the widget with the highest weight will receive the full delay.

By default, the weight of each widget is calculated as the Manhattan Distance from the top-left corner of the layout. You may set custom weights using MotionSceneScope.staggeredWeight on a per-widget basis, this essentially allows you to set a custom staggering order. Note that when you set custom weights, widgets without a custom weight will be ignored for this calculation and will animate without delay.

The remaining widgets will receive a portion of this delay, based on their weight calculated against each other.

This is the formula to calculate the progress delay for a widget i, where Max/MinWeight is defined by the maximum and minimum calculated (or custom) weight:

progressDelay[i] = maxStaggerDelay * (1 - ((weight[i] - MinWeight) / (MaxWeight - MinWeight)))

To simplify, this is the formula normalized against MinWeight:

progressDelay[i] = maxStaggerDelay * (1 - weight[i] / MaxWeight)

Example:

Given three widgets with custom weights [1, 2, 3] and maxStaggerDelay = 0.7f.

  • Widget0 will start animating at progress == 0.7f for having the lowest weight.

  • Widget1 will start animating at progress == 0.35f

  • Widget2 will start animating at progress == 0.0f

This is because the weights are distributed linearly among the widgets.

motionArc

Added in 1.1.0
var motionArcArc

The default Arc shape for animated layout movement.

Arc.None by default.

onSwipe

Added in 1.1.0
var onSwipeOnSwipe?

When not null, enables animating through the transition with touch input.

Example:

MotionLayout(
motionScene = MotionScene {
val textRef = createRefFor("text")
defaultTransition(
from = constraintSet {
constrain(textRef) {
top.linkTo(parent.top)
}
},
to = constraintSet {
constrain(textRef) {
bottom.linkTo(parent.bottom)
}
}
) {
onSwipe = OnSwipe(
anchor = textRef,
side = SwipeSide.Middle,
direction = SwipeDirection.Down
)
}
},
progress = 0f, // OnSwipe handles the progress, so this should be constant to avoid conflict
modifier = Modifier.fillMaxSize()
) {
Text("Hello, World!", Modifier.layoutId("text"))
}
See also
OnSwipe