Exploring MotionLayout KeyCycle
It’s been a while since MotionLayout got into our lives, and it has definitely been a bliss for our creativity as Android Developers.
We’ve learned quite a lot about Keyframes in Nicolas Roard’s wonderful blog post — Defining motion paths in MotionLayout. With that, KeyCycle
s were still shrouded in a cloud of mystery.
That is until John Hoford, Nicolas Roard, and Takeshi Hagikura took a deep dive into MotionLayout, and KeyCycle
s specifically, on their DroidKaigi 2019 talk aptly named — “Deep dive into MotionLayout”.
That excellent talk got me extremely motivated to get my hands dirty, to hopefully learn more about some of the new thoughts outlined :)
Let’s step right in!
What are KeyCycles?
A KeyCycle
is a highly-detailed, custom-made interpolator for a specific view, whereas the interpolator is influencing the entire scene, with a large focus on repetitive actions (hence the cycle in the name).
Since the main focus here is about cycles, you’ll divide your scene into frames.
Each KeyCycle
will define how many cycles the scene will have.
framePosition
: As aKeyFrame
,KeyCycle
has to know on which point of the scene to take action.target
: The view id.wavePeriod
: The number of waves that the scene performs in the current partial scene. You’ll learn more about waves in the next section.value
: The kind of animation you want to perform (e.g. rotation, translation, etc..)waveOffset
: A starting position for the value we chose at the current partial scene.waveShape
: The way you want your wave to behave. It can be a sin, cos, etc…
To summarize, you’ll divide your scene into partial scenes by using different framePosition
s. You‘ll specify the number of cycles you want on each part by using wavePeriod
.
In this terminology, A partial scene is defined as a dot position in between two other points.
The graph
One thing you should understand is that the graph you‘re created by using KeyCycle
s expresses the behavior of the value you chose (e.g. rotation, translation etc…).
For example, take a look at the following KeyFrameSet
:
Its graph look like this:
Changing the first item’s motion:waveOffset
to 10
will make the graph look like this, notice the starting point:
Here is the XML to represent this wave:
Since the value here represents rotation, the difference between the two graphs will make the following difference on the view at the given framePosition
:
A android:rotation
value of 20
means that on the top of each wave, the rotation needs to be 20
.
A motion:waveOffset
value of 20
, though, means that at the beginning of the current partial scene, the rotation needs to be 20
.
Exploring the Cycle Editor
Let’s see what we can do with the new tool :)
Start by downloading Cycle Editor.
Open your terminal and go to the folder where you downloaded Cycle Editor to, and run the following command:
java -jar CycleEditor.jar
You should see this beautiful window:
You’ll start by building a cycle that rotates 5 times by 20 degrees, from the beginning of the scene until frame 50 (half of the scene). Then, it’ll rotate 3 times between frames 50 and 90.
Copy the following into the text field on the bottom right of Cycle Editor:
Go to File ► parse xml.
Press the Play button to see what you achieved by now.
The should look like:
Cool! right?
At this point though, our button is a bit static. Let’s make it more bouncy :)
Add 3 more KeyCycle
s with a waveShape
value of bounce
, at frames 0, 50, and 100.
Since the waves of bounce are not crossing the X-axis, each wavePeriod
of it will be doubled, if you’ll set a wavePeriod
value of 2
, you’ll actually see 4 bounce waves.
Copy the following KeyCycles below your last KeyCycles:
Wrapping up this cycle
This has been a short, and hopefully sweet, introduction to using KeyCycles in MotionLayout. If you want to learn more, check out the official documentation at https://developer.android.com/reference/android/support/constraint/motion/MotionLayout#keycycle
KeyCycle
s seem very powerful and promising, and I’m looking forward to see what the MotionLayout folks have up their sleeves for next time! :)
That’s it for today! I hope you’ve enjoyed this quick recap.
If you have any questions, feel free to leave a comment below or reach out to me on twitter @maozgal! 🎉