TransitionScope
@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.
| See also | |
|---|---|
keyAttributes |
|
keyPositions |
|
keyCycles |
Summary
Public functions |
|
|---|---|
ConstrainedLayoutReference |
createRefFor(id: Any)Creates one |
Unit |
keyAttributes(Define KeyAttribute KeyFrames for the given |
Unit |
keyCycles(Define KeyCycle KeyFrames for the given |
Unit |
keyPositions(Define KeyPosition KeyFrames for the given |
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 |
OnSwipe? |
When not null, enables animating through the transition with touch input. |
Public functions
createRefFor
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
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.7ffor 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
var motionArc: Arc
The default Arc shape for animated layout movement.
Arc.None by default.
onSwipe
var onSwipe: OnSwipe?
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 |