Android Motion Layout

Filed Under: Android

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

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="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"
    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>
The 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="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">

    <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="http://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

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.

Leave a Reply

Your email address will not be published. Required fields are marked *

close
Generic selectors
Exact matches only
Search in title
Search in content
Search in posts
Search in pages