MotionLayout Tutorial For Android: Getting Started

Learn how to use the new ConstraintLayout subclass MotionLayout to add effects such as translation animations and alpha/color changes. By Filip Babić.

Leave a rating/review
Download materials
Save for later
Share

Meaningful motion is an important aspect of every modern application. Using animations, transitions, and text or view transformations, you can improve the UX (user experience) of your application and make your users happy. Unfortunately, this is not always simple. Android provides many different ways to animate objects on the screen and it’s always a challenge to find the right one. Sometimes you imagine complex animations, but you have to give up implementing them because of the time requirements.

Now you can solve all these problems with MotionLayout!

MotionLayout was been announced by Google at Google I/O 2018 and it’s a solution for mitigating the difficulty of creating complex animations. It provides a declarative, smart and clean way of building animations, without a single line of code.

As you’ll see below, MotionLayout extends ConstraintLayout, and so inherits all of its features. Through the internal use of ConstraintLayout and its helpers, MotionLayout allows you to animate color changes, alpha transitions and views, using as little as a single XML file.

In this tutorial you’ll see how you can combine a few animations, without much work, using MotionLayout. You’ll learn how to:

Getting Started

Note: This tutorial assumes you’ve got good knowledge of Android development, and that you’ve had previous experience with animations in Android apps. If you’re new to Android, please check out our Beginner Android series and the Android Animations tutorial

Before you begin, download the tutorial materials from the Download Materials button at the top or the bottom of the page. You’ll see the starter and final projects, which you’ll use throughout the tutorial.

Next, open up the build.gradle file under the app folder, and change the ConstraintLayout dependency version to 2.0.0-alpha2:

  • Animate alpha changes
  • Translate views
  • Interpolate color changes
  • Combine MotionLayout with other Android components
dependencies {
  - -
  // Support Libraries
  implementation "com.android.support:appcompat-v7:$support_lib_version"
  implementation 'com.android.support.constraint:constraint-layout:2.0.0-alpha2'
    - - -
  }

Finally, open up the onboarding_view.xml file, and change the root layout’s type to MotionLayout.

  <android.support.constraint.motion.MotionLayout 
      xmlns:android="http://schemas.android.com/apk/res/android"
      xmlns:app="http://schemas.android.com/apk/res-auto"
      android:id="@+id/onboardingRoot"
      android:layout_width="match_parent"
      android:layout_height="match_parent">

     - - -
  </android.support.constraint.motion.MotionLayout>

The goal of this tutorial is to create an on-boarding screen custom View, which will have a few animations. You’ll animate the next, skip and finish buttons, as well as the background color, like so:

In order to do this you need to understand what MotionScene, KeyFrameSet and the KeyAttribute are and how to use them. So let’s get started! :]

Introducing MotionLayout

If you look at the build.gradle file you updated earlier, you’ll see that there is no dependency for MotionLayout. This is because the MotionLayout is actually extends ConstraintLayout and the constraint-layout-2.0.0-alpha2 dependency includes everything you need.

MotionLayout uses a mechanism called the MotionScene to create all of the underlying animations. It is similar to Scene definitions which you can write to animate between screen states. They also define states in which a screen, and its elements, can be. Each of the scenes can have Transition, KeyFrameSet and ConstraintSet definitions. Let’s look at what each of them does.

MotionScene

With MotionLayout you can create your animations in a declarative way through the definition of a MotionScene in an XML file in the res/xml folder. This is where you can define everything the framework needs in order to run your animations. Thanks to the nature of ConstraintLayout, you can define the different states of the View components in the animation using different Constraint definitions, into a ConstraintSet element.

Animating doesn’t mean just moving objects but, in general, changing their properties in a time dependent fashion. You can move from state A to state B in many different ways with the definition of a Transition. Even if you know what your initial and final states are, you also need to define how this should happen and what are the possible intermediate states. This can be done using a KeyFrameSet definition.

It’s important to note that you define the MotionLayout in a file that is different from the one that contains the layout. You can apply the same MotionScene to different layout definitions, enhancing reusability. Applying an animation to a layout is as easy as assigning its reference as the value of the app:layoutDescription XML attribute of the MotionLayout element in the layout.

Transition

The name here is pretty self-explanatory. A Transition describes a change from state A to state B. You configure the start constraint set using the app:constraintSetStart attribute and the final one using app:constraintSetEnd. Then, when the progress of the Motionscene increases, the layout starts the transformation to the end constraint. Progress is just a number, ranging from 0 to 100, saying what percentage of the animation has currently been played.

The total duration of the animation is usually split in 100 different parts which are played, one after the other, at constant rate. If you need a different distribution in time of the animation, you need a custom interpolator that you can then set using the app:interpolator XML attribute.

KeyFrameSet

You can think of any animation as a sequence of frames you render on the screen during a given interval of time. If you want to animate a specific property from the value A to the value B, the framework chooses, by default, the shortest way. For instance, if A and B are positions on the screen, you’ll see the items moving through a straight line with constant speed.

You’ve just learned that if you want to change the way the frames are displayed in time you can use a different interpolator, but what if you want to change the path? Using the KeyFrameSet element, it’s possible to add some intermediate constraints that must be satisfied at some given times. For instance, you can tell the system to go from A to B through a path which contains C at time 20 and D at time 80.

To do this you can use the KeyAttribute or CustomAttribute elements, depending on what you need. You can use the former in case of more common View properties like position or alpha, but in the case of a component with custom properties, you need the latter. If you use CustomAttributes, you can use a custom String identifier, but it has to match the set method on the view. A good example is backgroundColor, as you can call setBackgroundColor() on a view.