MotionLayout is a
layout type that helps you manage motion and widget animation in your app.
MotionLayout is a subclass of ConstraintLayout
and builds upon its rich layout capabilities. As part of the ConstraintLayout
library, MotionLayout is available as a support library and is
backwards-compatible to
API level 14.
MotionLayout bridges the gap between layout transitions and complex motion
handling, offering a mix of features between the
property animation framework,
TransitionManager, and
CoordinatorLayout.
In addition to describing transitions between layouts, MotionLayout lets you
animate any layout properties, as well. Moreover, it inherently supports
seekable transitions. This means that you can instantly show any point within
the transition based on some condition, such as touch input. MotionLayout
also supports keyframes, enabling fully customized transitions to suit your
needs.
MotionLayout is fully declarative, meaning that you can describe any
transitions in XML, no matter how complex.
Design considerations
MotionLayout is intended to move, resize, and animate UI elements with which
users interact, such as buttons and title bars. Motion in your app should not be
simply a gratuitous special effect in your application. It should be used to
help users understand what your application is doing. For more information on
designing your app with motion, see the Material Design section on
Understanding motion.
Getting started
Follow these steps to start using MotionLayout in your project.
-
Add the
ConstraintLayoutdependency: To useMotionLayoutin your project, add theConstraintLayout2.0 dependency to your app'sbuild.gradlefile. If you're using AndroidX, add the following dependency:dependencies { implementation 'androidx.constraintlayout:constraintlayout:2.0.0-beta1' }If you aren't using AndroidX, add the following support library dependency:
dependencies { implementation 'com.android.support.constraint:constraint-layout:2.0.0-beta1' } -
Create a
MotionLayoutfile:MotionLayoutis a subclass ofConstraintLayout, so you can transform any existingConstraintLayoutinto aMotionLayoutby replacing the class name in your layout resource file, as shown in the following examples:AndroidX
<!-- before: ConstraintLayout --> <androidx.constraintlayout.widget.ConstraintLayout .../> <!-- after: MotionLayout --> <androidx.constraintlayout.motion.widget.MotionLayout .../>Support library
<!-- before: ConstraintLayout --> <android.support.constraint.ConstraintLayout .../> <!-- after: MotionLayout --> <android.support.constraint.motion.MotionLayout .../>Here's a full example
MotionLayoutfile that can be used to create the motion in figure 1:AndroidX
<?xml version="1.0" encoding="utf-8"?> <!-- activity_main.xml --> <androidx.constraintlayout.motion.widget.MotionLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/motionLayout" android:layout_width="match_parent" android:layout_height="match_parent" app:layoutDescription="@xml/scene_01" tools:showPaths="true"> <View android:id="@+id/button" android:layout_width="64dp" android:layout_height="64dp" android:background="@color/colorAccent" android:text="Button" /> </androidx.constraintlayout.motion.widget.MotionLayout>Support library
<?xml version="1.0" encoding="utf-8"?> <!-- activity_main.xml --> <android.support.constraint.motion.MotionLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/motionLayout" android:layout_width="match_parent" android:layout_height="match_parent" app:layoutDescription="@xml/scene_01" tools:showPaths="true"> <View android:id="@+id/button" android:layout_width="64dp" android:layout_height="64dp" android:background="@color/colorAccent" android:text="Button" /> </android.support.constraint.motion.MotionLayout> -
Create a MotionScene: In the previous
MotionLayoutexample, theapp:layoutDescriptionattribute references a MotionScene. A MotionScene is an XML resource file that contains all of the motion descriptions for the corresponding layout. To keep layout information separate from motion descriptions, eachMotionLayoutreferences a separate MotionScene. Note that definitions in the MotionScene take precedence over any similar definitions in theMotionLayout.Here's an example MotionScene file that describes the basic horizontal motion in figure 1:
<?xml version="1.0" encoding="utf-8"?> <MotionScene xmlns:android="http://schemas.android.com/apk/res/android" xmlns:motion="http://schemas.android.com/apk/res-auto"> <Transition motion:constraintSetStart="@+id/start" motion:constraintSetEnd="@+id/end" motion:duration="1000"> <OnSwipe motion:touchAnchorId="@+id/button" motion:touchAnchorSide="right" motion:dragDirection="dragRight" /> </Transition> <ConstraintSet android:id="@+id/start"> <Constraint android:id="@+id/button" android:layout_width="64dp" android:layout_height="64dp" android:layout_marginStart="8dp" motion:layout_constraintBottom_toBottomOf="parent" motion:layout_constraintStart_toStartOf="parent" motion:layout_constraintTop_toTopOf="parent" /> </ConstraintSet> <ConstraintSet android:id="@+id/end"> <Constraint android:id="@+id/button" android:layout_width="64dp" android:layout_height="64dp" android:layout_marginEnd="8dp" motion:layout_constraintBottom_toBottomOf="parent" motion:layout_constraintEnd_toEndOf="parent" motion:layout_constraintTop_toTopOf="parent" /> </ConstraintSet> </MotionScene>Note the following:
-
<Transition>contains the base definition of the motion.-
motion:constraintSetStartandmotion:constraintSetEndare references to the endpoints of the motion. These endpoints are defined in the<ConstraintSet>elements later in the MotionScene. -
motion:durationspecifies the number of milliseconds that it takes for the motion to complete.
-
-
<OnSwipe>lets you control the motion via touch.-
motion:touchAnchorIdrefers to the view that you can swipe and drag. -
motion:touchAnchorSidemeans that we are dragging the view from the right side. -
motion:dragDirectionrefers to the progress direction of the drag. For example,motion:dragDirection="dragRight"means that progress increases as you drag to the right.
-
-
<ConstraintSet>is where you define the various constraints that describe your motion. In this example, we define oneConstraintSetfor each endpoint of our motion. These endpoints are centered vertically (viaapp:layout_constraintTop_toTopOf="parent"andapp:layout_constraintBottom_toBottomOf="parent"). Horizontally, the endpoints are at the far left and right sides of the screen.
For a more detailed look at the various elements that MotionScene supports, see the MotionLayout examples.
-
Interpolated attributes
Within a MotionScene file, ConstraintSet elements can contain additional
attributes that are interpolated during transition. In addition to position and
bounds, the following attributes are interpolated by MotionLayout:
alphavisibilityelevationrotation,rotationX,rotationYtranslationX,translationY,translationZscaleX,scaleY
Custom attributes
Within a <Constraint>, you can use the <CustomAttribute> element to specify
a transition for attributes that aren't simply related to position or View
attributes.
<Constraint
android:id="@+id/button" ...>
<CustomAttribute
motion:attributeName="backgroundColor"
motion:customColorValue="#D81B60"/>
</Constraint>
A <CustomAttribute> contains two attributes of its own:
motion:attributeNameis required and must match an object with getter and setter methods. The getter and setter much match a specific pattern. For example,backgroundColoris supported, since our view has underlyinggetBackgroundColor()andsetBackgroundColor()methods.- The other attribute you must provide is based on the value type. Choose from
the following supported types:
motion:customColorValuefor colorsmotion:customIntegerValuefor integersmotion:customFloatValuefor floatsmotion:customStringValuefor stringsmotion:customDimensionfor dimensionsmotion:customBooleanfor booleans
Note that when specifying a custom attribute, you must define endpoint values in
both the start and end <ConstraintSet> elements.
Example: Change background color
Building on our previous example, let's have the view change colors as part of its motion, as shown in figure 2.
Add a <CustomAttribute> element to each ConstraintSet elements, as shown
below:
<ConstraintSet android:id="@+id/start">
<Constraint
android:id="@+id/button"
android:layout_width="64dp"
android:layout_height="64dp"
android:layout_marginStart="8dp"
motion:layout_constraintBottom_toBottomOf="parent"
motion:layout_constraintStart_toStartOf="parent"
motion:layout_constraintTop_toTopOf="parent">
<CustomAttribute
motion:attributeName="backgroundColor"
motion:customColorValue="#D81B60" />
</Constraint>
</ConstraintSet>
<ConstraintSet android:id="@+id/end">
<Constraint
android:id="@+id/button"
android:layout_width="64dp"
android:layout_height="64dp"
android:layout_marginEnd="8dp"
motion:layout_constraintBottom_toBottomOf="parent"
motion:layout_constraintEnd_toEndOf="parent"
motion:layout_constraintTop_toTopOf="parent">
<CustomAttribute
motion:attributeName="backgroundColor"
motion:customColorValue="#9999FF" />
</Constraint>
</ConstraintSet>
Additional MotionLayout attributes
In addition to the attributes in the example above, MotionLayout has other
attributes that you might want to specify:
app:applyMotionScene="boolean"indicates whether to apply the MotionScene. The default value for this attribute istrue.app:showPaths="boolean"indicates whether to show the motion paths as the motion is running. The default value for this attribute isfalse.app:progress="float"lets you explicitly specify transition progress. You can use any floating-point value from0(the start of the transition) to1(the end of the transition).app:currentState="reference"lets you specify a specificConstraintSet.app:motionDebuglets you display additional debug information about the motion. Possible values are "SHOW_PROGRESS", "SHOW_PATH", or "SHOW_ALL".
Additional resources
For more information on MotionLayout, see the following links:
- Using MotionLayout to Animate Android Apps (codelab)
- MotionLayout examples
- MotionLayout / ConstraintLayout Samples (GitHub)
- Introduction to MotionLayout (part I)
- Introduction to MotionLayout (part II)
- Introduction to MotionLayout (part III)
- Introduction to MotionLayout (part IV)