Getting Started with the Motion Editor in Android Studio 4.0

Android Studio 4.0 has been released in the stable channel! 🥳 What does this mean for us? Well, the new Motion Editor is in Android Studio 4.0 and if you are someone who prefers to use the stable version of tooling, this is probably your first look at the Motion Editor.

In this blog post, we are going to have a look at the different aspects of the new Motion Editor and how you can create a MotionLayout animation within the Editor. 

Creating a new MotionLayout Animation

MotionLayout itself is part of the ConstraintLayout beta, so to ensure you have the feature, make sure your ConstraintLayout dependency is on the following (or higher):

implementation 'androidx.constraintlayout:constraintlayout:2.0.0-beta6'

To create a new MotionLayout animation, head to your layout folder and create a new Layout Resource File. Give it a meaningful name and select MotionLayout as the root layout. 

Once the file is created, you will see the MotionLayout root element requires a layoutDescription tag to be set on it. This is the MotionScene file that should be linked to the layout. 

What is a MotionScene? 🎬

A MotionScene object is the description for how the MotionLayout should animate its components. We will define this MotionScene in another XML file, in the xml directory in our res folder. It contains the definitions for the different layout states that the layout can be in (ConstraintSet) and the mechanism for transforming between these states (Transition).

To add a new MotionScene file, you can click on the red light bulb that appears next to the MotionLayout tag and then click the action to “Generate MotionScene file”:

This will then automatically create a new MotionScene XML file in the xml directory. The default MotionScene file looks as follows:

<?xml version="1.0" encoding="utf-8"?>
<
MotionScene xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">

<
ConstraintSet android:id="@+id/start">
<
Constraint android:id="@+id/widget" />
</
ConstraintSet>

<
ConstraintSet android:id="@+id/end">
<
Constraint android:id="@id/widget" />
</
ConstraintSet>

<
Transition
app:constraintSetEnd="@id/end"
app:constraintSetStart="@+id/start" />
</
MotionScene>

You will need to remove the Constraint that references widget from the generated MotionScene file, since our new layout doesn’t have that widget inside it. Our MotionLayout layout file looks as follows (Note: You may have to add the appprefix to the layoutDescription tag):

<?xml version="1.0" encoding="utf-8"?>
<
androidx.constraintlayout.motion.widget.MotionLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
app:layoutDescription="@xml/motion_layout_demo_scene">

</
androidx.constraintlayout.motion.widget.MotionLayout>

Now at this point we have our layout setup, so we can go ahead and start working in the “Design” view. 

Let’s take a look at the new controls that’ll appear when a MotionLayout object is selected in the Component Tree. 

There is a new section with the different resting states, the transitions between them and new buttons to add these kinds of elements. 

MotionLayout resting states (ConstraintSet) 🛌

The intention with MotionLayout is that the whole layout has different states that it can take on and animate between. These are defined with the ConstraintSet tag. I like to think of them as “resting” states, since they are where the layout will end up resting after the animation has finished. 

A look at the different resting states defined in our default MotionScene file

When you click on any of the states, i.e. the “base state”, start or end state, the editor updates to show you what that state looks like. Generally, when adding new views and setting the initial state of the view, you want to make sure you have the “base state” (The one that says “Motion Layout”) selected. 

To have different constraints set in the different states, you would select the relevant state that you want to edit and change the constraints, as if you are building a normal layout with ConstraintLayout

Let’s add a button to our layout. Make sure the “base state” is selected, and then drag in a new button from the Palette selection. We then give it top and start constraints. 

Adding start and top constraints for the base state

Now select the end state that we have defined. We can now edit the button’s constraints to be constrained to the bottom and end of the screen. When we toggle between the different states, we can see that the button is at the top in the start state and at the bottom in the end state. 

Adding start and top constraints for the base state

Now we have our two states with different constraints, let’s see how we can add a new state if we wanted one.

Adding new Motion Layout States ➕

To add a new resting state, click on the first button above the states:

This will prompt you to enter a name for the state and if it should be based on any other state. What this means is that it will take all the constraints set in the state you base it on. If you just want one or two things different from another state, you can set a base state to inherit from. 

By default, all states inherit constraints from the base state of MotionLayout (i.e. The constraints that are set in the layout file). This is why we didn’t need to set constraints for the startstate, it just inherited the state from the MotionLayout itself.

Create a new resting state (ConstraintSet)

The new state will now appear in the list inside the editor. Similar to the above actions of adding constraints per state, we can select this state and add as many constraints as we would like for this state. 

Our newly added ConstraintSet (state)

Transitions between states 🔁

We have our different states set up and we know how we want this animation to run. We want our button to animate from the top left corner to the bottom right. But how do we make this happen?

With Transitions, we can specify which state is the start state and which is the end state. Running the transition between them will automatically animate between the different ConstraintSets that have been defined in each state. Like magic! Let’s take a look.

Playing MotionLayout animations in Android Studio ⏯

If you recall from the beginning of this article, the lines with arrows above the states represent the transitions between them. When you click on the line, the editor will show you the transition information below the states and you will be able to play the animation between those two states. 

You can slow down or speed up the animation by clicking on the 1.0x button near the play button and choosing a different speed option. 

Adding new Transitions

Like adding a new state (ConstraintSet), we can add as many Transitions between states as we want. To do this, click on the “Add transition” button:

We can then specify the id of the transition, which state to start with and which should be the end state of the transition. 

Define the properties of the new transition

After defining the new transition, it will appear in the Motion Editor UI. Clicking on the transition and playing it, we can see how the transition will animate between these two defined states. 

The new transition defined.

Automatic transition of MotionLayout on Button Click

We’ve created a basic animation with the Motion Editor and we are happy with our transition, but when we run the layout on our device nothing happens. We need to set up some automatic transitions when a button is clicked. Luckily we can do that from the editor too. 

To add an automatic transition when the button is clicked, select the 3rd button to add a new listener:

We select “Click listener” since we want to add it on the button click. Then we select which transition should run and which view the click listener should be added to: 

Now when you run the application on your device and click on the button, it will automatically transition to the end state that we defined. 

MotionLayout automatic transition between ConstraintSets (states)

What if we wanted to get a bit fancier with our animation? For instance, we want the button to start off fully transparent and by 27% of the animation, it should be fully visible. 

To do this, we need to look at using KeyFrames to create even more dynamic animations.

Adding a KeyFrame to a transition

We first need to set the start state to have an alpha value of 0.0 for the button. Then the end state should have an alpha of 1.0, since it needs to be fully visible at the end. 

Adding alpha component animation

Now that we have the ConstraintSets defining the alpha for the start and end states, we need to define the KeyFrame at 27% to set the alpha of the button to 1.0. To do that, click on the KeyFrames button that appears when selecting a transition in the Motion Editor. 

Add KeyFrame button

We then select “KeyAttribute” when presented with the different options. KeyAttribute allows us to set an attribute on the view at a certain position in the animation (Attributes such as alpha, rotation, scale or elevation).

Different options for adding a KeyFrame

Now we choose the target view, the position in the animation (Out of 100%) and the attribute that we want this to target. We set the position to 27 and we target the alpha attribute. 

Now you will see the KeyFrame item get added to the “Transition list”. 

Selecting the item and opening the “Attributes” panel on the side, we can see the KeyAttribute defines the alpha, motionTarget and the framePosition. We want to change this alpha value to be 1.0 now, since we want the button fully visible at 27%. 

If we scrub the “animation position tracker” in the editor we can visibly see how this animation progresses from 0 to 1 during the 0–27% of the animation and from 27% onwards it is fully opaque. 

Scrubbing the animation in the Motion Editor.

There are plenty of other KeyFrame options available to you as seen in the first drop down list. If you want to change other properties during the animation, you can use KeyPosition, KeyTrigger, KeyCycle or KeyTimeCycle to achieve different effects. 

KeyFrames are best for when you want a part of the animation to be different or to change during the transition between start and end state. 

Wrapping up 🎁

The new Motion Editor in Android Studio makes working with MotionLayout so much easier than before. I am really enjoying working with it and previewing my animations inside Android Studio without needing to run it on a device. 

I would love to see what you build with MotionLayout and the new Motion Editor, so please show me what you have made on Twitter @riggaroo.

Till next time!

References