-
Notifications
You must be signed in to change notification settings - Fork 173
Compose MotionLayout DSL Syntax
Added first in 1.1.0-alpha04.
The MotionScene takes a collection of ConstraintSets and Transitions.
Each ConstraintSet represents a specific Layout and each Transition represents the animation description between two ConstraintSets.
So the most basic MotionLayout requires two ConstraintSets and a default Transition that defines the initial state.
MotionLayout(
MotionScene { // this: MotionSceneScope
val textRef = createRefFor("text")
defaultTransition(
from = constraintSet { // this: ConstraintSetScope
constrain(textRef) { // this: ConstrainScope
bottom.linkTo(parent.bottom)
start.linkTo(parent.start)
}
},
to = constraintSet { // this: ConstraintSetScope
constrain(textRef) { // this: ConstrainScope
top.linkTo(parent.top)
end.linkTo(parent.end)
}
}
) { // this: TransitionScope
onSwipe = OnSwipe(
anchor = textRef,
side = SwipeSide.End,
direction = SwipeDirection.End,
mode = SwipeMode.Spring,
onTouchUp = SwipeTouchUp.AutoComplete
)
}
},
progress = 0f,
Modifier.fillMaxSize()
) {
Text("Hello, World", Modifier.layoutId("text"))
}
All ConstraintSets and Transitions must be defined within the scope of the MotionScene. You may add existing ConstraintSet
or Transition
objects with addConstraintSet
and addTransition
respectively.
Note that the name given to the ConstraintSets should match the names defined in the Transition.
val cSet1 = ConstraintSet { }
val cSet2 = ConstraintSet { }
val transition = Transition(from = "start", to = "end") { }
MotionScene {
addConstraintSet(name = "start", cSet1)
addConstraintSet(name = "end", cSet2)
addTransition(name = "default", transition)
}
Defining the onSwipe
allows you to control the animation progress with gestures.
The most basic OnSwipe
requires the anchor
to track, direction
and side
of the Swipe.
Transition {
val boxRef = createRefFor("box")
onSwipe = OnSwipe(
anchor = boxRef,
side = SwipeSide.Middle,
direction = SwipeDirection.Up
)
}
Parameters
-
anchor: ConstrainedLayoutReference
- The Composable you wish your finger to track -
side: SwipeSide
- The side of the anchor Composable your finger will track -
direction: SwipeDirection
- direction of you motion -
dragScale: Float
- a scale factor to magnify your motion -
dragThreshold: Float
- Minimum drag distance -
dragAround: ConstrainedLayoutReference?
- -
limitBoundsTo: ConstrainedLayoutReference?
- -
onTouchUp: SwipeTouchUp = SwipeTouchUp.AutoComplete
- What happens on lifting your finger -
mode: SwipeMode
- Spring or Velocity mode
Defines the animation of the swipe after lifting your finger. It may be either Velocity
or Spring
.
Note that each mode has its own parameters.
Velocity
fun Velocity(
maxVelocity: Float = 4f,
maxAcceleration: Float = 1.2f
)
Spring
fun Spring(
mass: Float = 1f,
stiffness: Float = 400f,
damping: Float = 10f,
threshold: Float = 0.01f,
boundary: SpringBoundary = SpringBoundary.Overshoot
)
You may define KeyAttributes, KeyPositions and KeyCycles.
With each type of KeyFrame you must indicate which widgets its referencing at its values at different positions of the progress (from 0 to 100).
For example:
Transition {
val imgRef = createRefFor("img")
keyAttributes(imgRef) {
// Rotate 45 degrees left at 25% of the progress
frame(25) {
rotationZ = -45f
}
// Rotate 45 degrees right at 75% of the progress
frame(75) {
rotationZ = 45f
}
}
}
See ConstraintSet DSL.