Pull the KeyTrigger with MotionLayout
Just shy of the holidays, the ConstraintLayout team released a new alpha version of MotionLayout, introducing KeyTriggers (and more). If you haven’t used MotionLayout before, I recommend taking a look at Nicolas Roard series about it. But let’s get started!
Before MotionLayout, to achieve the FloatingActionButton
effect from the above video you most likely used a CoordinatorLayout
with a CoordinatorLayout.Behavior
.
MotionLayout makes doing this possible in an easier way requiring less code using KeyTrigger
— so let’s shoot!
What is KeyTrigger?
KeyTrigger
allows you to have MotionLayout call a method on the specified target at a specified percentage of frames. Since MotionLayout is using reflection internally, the method can’t be called with any parameters.
We can define a KeyTrigger
inside a KeyFrameSet
in a Transition
inside a MotionScene
:
Pulling the KeyTrigger
Before we pull the trigger, we need to provide it with a few attributes:
framePosition
: The frame around which the trigger should be fired, from0
to100
target
: The ID of the target, e.g.motion:target="@id/fab"
onCross
|onPositiveCross
|onNegativeCross
: The method to call on thetarget
, e.g.motion:cross="toggleVisibility"
What’s with all the crosses?
If you have a toggling method like FloatingActionButton#toggleVisiblity
, you can use onCross
: It’s being called regardless of whether the frame value is decreasing or increasing.
For other use cases, you may want to call different methods depending on whether the frame value is increasing or decreasing. You might be using a transition like this:
With this, when the frame value is increasing, we know that we are scrolling down, while when the frame value is decreasing, we know that we are scrolling up.
Finally, a full example!
In the end, to achieve the visibility toggling effect from the video, your MotionScene could look like this:
When the framePosition
increases (user scrolls down) and hits around frame 10, the FloatingActionButton will be shown. When the framePosition
decreases (user scrolls up) and hits around 20, the FAB is hidden again.
Adding Slack to the KeyTrigger
For each KeyTrigger
, you can set the triggerSlack
value. Say your KeyTrigger
is to be triggered at framePosition ~ 50
and just around that frame, the user starts dragging in the opposite direction so that the progress decreases to 0.49. triggerSlack
prevents your trigger from being fired multiple times when that happens. By default, triggerSlack
is set to 0.1
which should avoid jiggle-juggle for most interactions.
Thanks for reading! If you’d like to get to know more about MotionLayout, join my talk at Chicago Roboto in April!
For the full example, please check the ConstraintLayout samples repository on Github.
Thanks to Juhani Lehtimäki and Craig Russell for proofreading and coming up with puns!