MotionLayout
A MotionLayout is a ConstraintLayout which allows you to animate layouts between various states. MotionLayout links to and requires a MotionScene file.
MotionScene
A MotionScene file can contain all that is needed for specifying the animation:
the
ConstraintSets
usedthe transition between those
ConstraintSets
keyframes, touch handling, etc.
Motion scene files usually contain two constraint sets: one for the beginning of the animation and one for the end.
Make sure that the ConstraintLayout import version is at least ConstraintLayout 2.0.0-alpha1.
Switching to a MotionLayout
MotionLayout
The MotionLayout
is a subclass of ConstraintLayout
. So to transform a ConstraintLayout
to a MotionLayout
we need to only replace the class name from :
<android.support.constraint.ConstraintLayout .../>
to :
<android.support.constraint.motion.MotionLayout .../>
Creating the MotionScene
MotionScene
To create our MotionScene
we first need to create an XML directory in our resources file. Then we create a new XML file, called motion_scene_main.xml

Our MotionScene
should contain a transition attribute where we will specify the starting and ending constraints, how long it should last and we are also going to add a gesture handler.
<?xml version="1.0" encoding="utf-8"?>
<MotionScene xmlns:app="http://schemas.android.com/apk/res-auto">
<Transition
app:constraintSetEnd="@layout/activity_main_end"
app:constraintSetStart="@layout/activity_main_start"
app:duration="1000">
<OnSwipe
app:dragDirection="dragUp"
app:touchAnchorId= "@id/second_bg"
app:touchAnchorSide="top" />
</Transition>
</MotionScene>
If you want to learn more about the gesture handlers check the documentation here.
Connecting the dots
As we mentioned above, the MotionLayout
links to the MotionScene
. But right now our MotionLayout
is still not aware that we created that file. So we need to go back to the activity_main_start.xml
file, add a layoutDescription
attribute to the widget, and set its value to the name of the motion scene file.
<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:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
android:background="@color/colorBgDark"
app:layoutDescription="@xml/motion_scene_main">
....
</android.support.constraint.motion.MotionLayout>
OOPS!
If we now try to enter the design mode of that layout we will see that it cannot render. The reason for this is that all the widgets found in the starting constraint should also be included to the ending one and vice versa. So we need to copy paste the views we haven't added so far to both of our layouts.
<?xml version="1.0" encoding="utf-8"?>
<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:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
android:background="@color/colorBgDark"
app:layoutDescription="@xml/motion_scene_main">
<!-- Circle ImageView -->
<!-- Main ImageView -->
<!-- CardView -->
<!-- ImageView Paw 1-->
<!-- ImageView Paw 2-->
<!-- ImageView Paw 3-->
<!-- ImageView Paw 4-->
<!-- ImageView Paw 1-->
<!-- Second Background View-->
<ImageView
android:id="@+id/iv_leaf_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="28dp"
android:layout_marginBottom="150dp"
android:rotation="80"
android:src="@drawable/ic_leaf"
app:layout_constraintBottom_toBottomOf="@+id/guideline_horizontal20"
app:layout_constraintEnd_toEndOf="@+id/guideline_verticalHalf"
tools:ignore="ContentDescription" />
<ImageView
android:id="@+id/iv_leaf_2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="136dp"
android:layout_marginBottom="150dp"
android:rotation="15"
android:src="@drawable/ic_leaf"
app:layout_constraintBottom_toBottomOf="@+id/guideline_horizontal20"
app:layout_constraintEnd_toEndOf="parent"
tools:ignore="ContentDescription" />
<!-- Guidelines -->
</android.support.constraint.motion.MotionLayout>
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.motion.MotionLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/colorBgDark"
xmlns:app="http://schemas.android.com/apk/res-auto">
<!-- Circle ImageView -->
<!-- ImageView Leaf 1-->
<!-- ImageView Leaf 2-->
<!-- ImageView Leaf 1-->
<!-- CardView-->
<ImageView
android:id="@+id/iv_main"
android:layout_width="180dp"
android:layout_height="180dp"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
android:layout_marginBottom="8dp"
android:scaleType="centerInside"
android:src="@drawable/alex"
app:layout_constraintBottom_toBottomOf="@+id/second_bg"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.343"
tools:ignore="ContentDescription" />
<ImageView
android:id="@+id/iv_paw_1"
android:layout_width="65dp"
android:layout_height="wrap_content"
android:layout_marginStart="88dp"
android:rotation="30"
android:src="@drawable/ic_paw"
app:layout_constraintStart_toStartOf="@+id/iv_main"
app:layout_constraintTop_toTopOf="@id/iv_main"
tools:ignore="ContentDescription" />
<ImageView
android:id="@+id/iv_paw_2"
android:layout_width="65dp"
android:layout_height="wrap_content"
android:layout_marginStart="112dp"
android:layout_marginTop="56dp"
android:rotation="45"
android:src="@drawable/ic_paw"
app:layout_constraintStart_toStartOf="@+id/iv_main"
app:layout_constraintTop_toTopOf="@id/iv_main"
tools:ignore="ContentDescription" />
<ImageView
android:id="@+id/iv_paw_3"
android:layout_width="65dp"
android:layout_height="wrap_content"
android:layout_marginEnd="92dp"
android:rotation="-30"
android:src="@drawable/ic_paw"
app:layout_constraintEnd_toEndOf="@+id/iv_main"
app:layout_constraintTop_toTopOf="@id/iv_main"
tools:ignore="ContentDescription" />
<ImageView
android:id="@+id/iv_paw_4"
android:layout_width="65dp"
android:layout_height="wrap_content"
android:layout_marginTop="56dp"
android:layout_marginEnd="104dp"
android:rotation="-45"
android:src="@drawable/ic_paw"
app:layout_constraintEnd_toEndOf="@+id/iv_main"
app:layout_constraintTop_toTopOf="@id/iv_main"
tools:ignore="ContentDescription" />
<!-- Second Background View -->
<!-- Guidelines -->
</android.support.constraint.motion.MotionLayout>
Last updated