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
ConstraintLayout
dependency: To useMotionLayout
in your project, add theConstraintLayout
2.0 dependency to your app'sbuild.gradle
file. If you're using AndroidX, add the following dependency:Groovy
dependencies { implementation "androidx.constraintlayout:constraintlayout:2.2.0-alpha10" // To use constraintlayout in compose implementation "androidx.constraintlayout:constraintlayout-compose:1.1.0-alpha10" }
Kotlin
dependencies { implementation("androidx.constraintlayout:constraintlayout:2.2.0-alpha10") // To use constraintlayout in compose implementation("androidx.constraintlayout:constraintlayout-compose:1.1.0-alpha10") }
-
Create a
MotionLayout
file:MotionLayout
is a subclass ofConstraintLayout
, so you can transform any existingConstraintLayout
into aMotionLayout
by 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
MotionLayout
file 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
MotionLayout
example, theapp:layoutDescription
attribute 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, eachMotionLayout
references 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:constraintSetStart
andmotion:constraintSetEnd
are references to the endpoints of the motion. These endpoints are defined in the<ConstraintSet>
elements later in the MotionScene. -
motion:duration
specifies the number of milliseconds that it takes for the motion to complete.
-
-
<OnSwipe>
lets you control the motion via touch.-
motion:touchAnchorId
refers to the view that you can swipe and drag. -
motion:touchAnchorSide
means that we are dragging the view from the right side. -
motion:dragDirection
refers 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 oneConstraintSet
for 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
:
alpha
visibility
elevation
rotation
,rotationX
,rotationY
translationX
,translationY
,translationZ
scaleX
,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:attributeName
is required and must match an object with getter and setter methods. The getter and setter must match a specific pattern. For example,backgroundColor
is 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:customColorValue
for colorsmotion:customIntegerValue
for integersmotion:customFloatValue
for floatsmotion:customStringValue
for stringsmotion:customDimension
for dimensionsmotion:customBoolean
for 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:motionDebug
lets 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)