Pull the KeyTrigger with MotionLayout

Jossi Wolf
Snapp Mobile
Published in
3 min readFeb 20, 2019

--

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 .

Our old Layout
The 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, from 0 to 100
  • target: The ID of the target, e.g. motion:target="@id/fab"
  • onCross | onPositiveCross | onNegativeCross: The method to call on the target , 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:

Kindly taken from the ConstraintLayout/MotionLayout Samples Repository

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 to John Hoford for the explanation!

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!

Finally, some pictures of my rabbits

--

--

Jossi Wolf
Snapp Mobile

Software Engineer @Google working on Jetpack Compose. I like Kotlin, Animations and Rabbits! speakerdeck.com/jossiwolf