In this tutorial, we’ll be discussing and implementing the MotionLayout in our android application.
Android MotionLayout
Android MotionLayout is introduced with Constraint Layout 2.0. The idea is to create interactive fluid motion like UI layouts with ease.
Previously, we used to use the following things to animate components in our application.
- PropertyAnimation
- Animated Vector Drawable
- CoordinatorLayout
- Layout Transitions
Motion Layout aims to make it better and easier to animate layouts.
To use motion layouts, add the following dependency:
implementation 'androidx.constraintlayout:constraintlayout:2.0.0-beta2'
A MotionLayout can be used in place of ConstraintLayout. This is because a MotionLayout has all the properties of a ConstraintLayout(and much more as well shall see!).
A MotionLayout comprises of three core things:
- Starting layout
- Ending layout that has the ending constraints
- Motion scene
Starting and ending layouts are basic xml layout.
A motion scene is where we define the underlying motion.
We do so inside a <MotionScene/>
tag.
It can contain a Transition, ConstraintSet, KeyFrameSet, Touch Handling.
In this tutorial, we’ll focus on Transitions and Touch Handling.
Let’s look at a sample android application in which we will implement a swipe function on a button on the basis of which the layout would swap its content. We call it SwipeToSwap Application
Project Structure

Android Motion Layout Project Structure
The motion scene is defined in the res | xml folder
Code
The code for the activity_main_start.xml layout is given below:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.motion.widget.MotionLayout xmlns:android="https://schemas.android.com/apk/res/android"
xmlns:app="https://schemas.android.com/apk/res-auto"
xmlns:tools="https://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layoutDescription="@xml/motion_scene"
tools:context=".MainActivity">
<TextView
android:id="@+id/textOne"
android:text="Constraint Layout 2.0"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginStart="8dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"/>
<Button
android:id="@+id/button"
android:text="SWIPE TO SWAP"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clickable="false"
android:layout_marginTop="16dp"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
app:layout_constraintTop_toBottomOf="@+id/textOne"
app:layout_constraintStart_toStartOf="parent"/>
<TextView
android:id="@+id/textTwo"
android:text="Hello Motion Layouts"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:layout_marginEnd="8dp"
app:layout_constraintTop_toBottomOf="@+id/button"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>
</androidx.constraintlayout.motion.widget.MotionLayout>
app:layoutDescription
is where we set the motion scene on the MotionLayout.The code for the activity_main_end.xml
layout is given below. It represents the end state after the transition.
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.motion.widget.MotionLayout xmlns:android="https://schemas.android.com/apk/res/android"
xmlns:app="https://schemas.android.com/apk/res-auto"
xmlns:tools="https://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:id="@+id/textTwo"
android:text="Hello Motion Layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginStart="8dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"/>
<Button
android:id="@+id/button"
android:text="SWIPE TO SWAP"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clickable="false"
android:layout_marginTop="16dp"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
app:layout_constraintTop_toBottomOf="@+id/textTwo"
app:layout_constraintEnd_toEndOf="parent" />
<TextView
android:id="@+id/textOne"
android:text="Constraint Layout 2.0"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:layout_marginEnd="8dp"
app:layout_constraintTop_toBottomOf="@+id/button"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>
</androidx.constraintlayout.motion.widget.MotionLayout>
The code for the motion_scene.xml
file is given below:
<?xml version="1.0" encoding="utf-8"?>
<MotionScene
xmlns:motion="https://schemas.android.com/apk/res-auto">
<Transition
motion:constraintSetStart="@layout/activity_main_start"
motion:constraintSetEnd="@layout/activity_main_end"
motion:duration="1000">
<OnSwipe
motion:touchAnchorId="@id/button"
motion:touchAnchorSide="top"
motion:dragDirection="dragRight"/>
</Transition>
<Transition
motion:constraintSetStart="@layout/activity_main_end"
motion:constraintSetEnd="@layout/activity_main_start"
motion:duration="1000">
<OnSwipe
motion:touchAnchorId="@id/button"
motion:touchAnchorSide="top"
motion:dragDirection="dragLeft"/>
</Transition>
</MotionScene>
OnSwipe is a type of gesture performed on the UI component.
The UIComponent is specified in the touchAnchorId
along with the swipe direction.
Note: Other interactive gestures such as click can also be set in the following way:
<OnClick
app:target="@+id/button"
app:mode="transitionToEnd"/>
The output when the above application is run on an emulator is given below:

Android Motion Layout Output
That sums up this introductory tutorial on MotionLayout.
You can download the AndroidMotionLayout project from the link below or view the full source code in our Github Repository.