DEV Community

Cover image for Android MotionLayout – Clearing weather
Inspire Coding
Inspire Coding

Posted on • Updated on • Originally published at inspirecoding.app

Android MotionLayout – Clearing weather

In this tutorial we are going to build up a simple clearing weather animation using MotionLayout.

This animation will contain a changing background color, and 2 moving clouds, which are going to move out to the left and right of the screen.

Clearing weather

We are going to implement a click listener also. It means, the animation will start only when we click on it.

When the animation is started and finished, then we gonna show a Toast message. So, we gonna learn how to add events to the states of the Transition as well.

Android WeatherApp Course

This tutorial is part of my WeatherApp course. In this course you can build up a whole application using the OpenWeatherMaps API.
If you would like to do this course, then you can find it under the link: Android WeatherApp course

MotionLayout

MotionLayout is a layout type, where we can animate the views inside of a layout. Because MotionLayout is the subclass of ConstraintLayout, we can use all of its cool features.

In a MotionLayout we can animate not only the transitions between the layouts, we can either animate the layout properties as well.

And one more awesome thing, that we can handle events like click and swipe also. Using this feature we can build up much better user interfaces to reach better user experiences.

MotionLayout uses XML to declare the transitions no matter how complex it is.

Tags

Before we can start the implementation of the tutorial, we should clarify some tags, what we are going to use for this example animation.

These tags are identified in an XML file, which describes the animation. For example the start and the end transitions, moreover the changes of the attributes.

This XML file will be automatically generated by Android Studio when we will convert the ConstraintLayout to MotionLayout.

The name of this XML is MotionScene, which describes the animation.

There are many tags, but from them we gonnna use the below ones.

  • <Transition>: It specifies the animation duration, trigger and how should the views move.
    • <OnClick>: As we have talked about, we can add a click event to the transition…
    • <KeyFrameSet>: Inside of this tag we can add some changes to the views and we can specify in which position of the transition should be done the attribute-change.
  • <ConstraintSet>: This tag will specify the start and the end constraints of the transition.
    • <Constraint>: With this attribute we can match views from the layout XML file to the corresponding ConstraintSet.
      • <Layout>: It will describe the above mentioned views.
      • <PropertySet> and <Transform>: With these attributes we can specify some properties of the above mentioned views.

It can be that after this description you feel yourself a bit lost, but now we will start to implement the sample transition and these attributes gonna be cleaner, I promise. 😎

Step 1 – Create new project

Our first step is to create a whole new project. For this, launch Android Studio. If you see the “Welcome page”, then click on the “Start a new Android Studio project”. If you have an open project, then from the “File” menu select “New”, then “New Project”. After thet, this window will popup.

Create a new project
Here select the “Empty Activity” option. In the next window, we should provide some information about the newly created app.

Create a new project

This tutorial will be written in Kotlin. So, select from the dropdown list the Kotlin language.

From the next list of the “Minimum SDK” select API 21. In our case API 21 gonna be enough.

If you are done, click on the “Finish” button. The build can take few minutes. Be patient! 😉

When the build has been finished, then you should see the open MainActivity::class and next to this the activity_main.xml files.

Step 2 - Update dependency

We are going to start this chapter by updating the dependencies of ConstraintLayout for the app. First, open the Module build.gradle file from the left Project pane.

Module build.gradle

Then in the dependencies{} section find this line:
implementation ‘androidx.constraintlayout:constraintlayout:1.1.3’

To start using MotionLayout in our project, we have to update the version of ConstraintLayout at least to version 2.0.0. You can find the highest version under the link: Constraintlayout

When this tutorial was writen, this version was 2.0.0-rc1, so update the above implementation line to

implementation ‘androidx.constraintlayout:constraintlayout:2.0.0-rc1‘

Next sync the project by clicking on the Sync now button at the top right corner of Android Studio.

That’s all what we have to do to start using MotionLayout in our project.

Step 3 - Convert to MotionLayout

Next we will convert ConstraintLayout of the activity_main.xml file to MotionLayout. To do this, open it from the res > layout folders.

Open the design view at the right side of Android Studio. Then go to the Component Tree pane. Click on ConstraintLayout with the right mouse button and select the “Convert to MotionLayout” option.

Convert to MotionLayout

After the conversation you should have the below window which is the MotionScene of the activity_main.xml file.

MotionScene

  1. This layout describes the starter position of the ConstraintSet
  2. … and this is the end.
  3. After the conversation, our layout got a new attribute also, which describes the MotionScene of the layout. You can find this XML file in the res > xml folder called activity_main_scene.xml.
  4. Using the first icon you can add new ConstraintSets, which is a new state what you can start for example from the end of the current MotionScene. With the second icon you can add transitions and the third icon is for adding click or swipe event to the transitions.
  5. This is called Transition. Here you can play with the animation and check what is going to happen with the layout during the animation.

Step 4 - The assets

Before we can start to implement the layout and the MotionScene, we have to add the clouds, the sun and 2 new colors to the colors.xml file. Because this step is not the main part of this clearing weather tutorial, we will just add them by downloading the below ZIP file.
Clearing Weather assets

After downloading, unzip the file into the res folder of your project.

Step 5 - The layout

The next step is the implementation of the starter layout. So, open the activity_main.xml file from the res > layout folders and paste into it the below xml code.

The layout will contain 2 Views, which will be the background and 3 ImageViews representing the clouds and the sun.

activity_main.xml
<?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/activity_main_scene"
    tools:context=".MainActivity">
    <View
        android:id="@+id/view_background_gray"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:alpha="1"
        android:background="@color/light_grey"/>
    <View
        android:id="@+id/view_background_blue"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:alpha="0"
        android:background="@color/light_blue"/>
    <ImageView
        android:id="@+id/iv_sun"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/ic_sun"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
    <ImageView
        android:id="@+id/iv_cloud_white"
        android:layout_width="200dp"
        android:layout_height="200dp"
        android:elevation="1dp"
        android:src="@drawable/ic_cloud_white"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintHorizontal_bias="0.2"
        app:layout_constraintVertical_bias="0.45"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
    <ImageView
        android:id="@+id/iv_cloud_grey"
        android:layout_width="150dp"
        android:layout_height="150dp"
        android:src="@drawable/ic_cloud_gray"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintVertical_bias="0.55"
        app:layout_constraintHorizontal_bias="0.8"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.motion.widget.MotionLayout>
Enter fullscreen mode Exit fullscreen mode

Step 6 - The clearing weather animation

Finally in this step, we can start the implementation of the clearing weather animation.

There are 2 ways to do thet. Before Android Studio 4.0 you could do that only using the XML file. From version 4.0 the developers can use a graphical interface, which is the MotionScene. About this we have talked already. You can open this screen when you open the activity_main.xml file and switch to the design view using the icons at the top right corner of Android Studio.

In this tutorial we gonna do that manually. So we gonna use the design view.

The MotionScene

The start ConstraintSet

As you can see, the starter ConstraintSet is already done, because we have inserted the above layout. Note the alpha property of the view_background_gray View.

The start ConstraintSet

Now select the end ConstraintSet.

The end ConstraintSet

First, we gonna change the transparency of the 2 views. We can do that by setting their alpha property.

From the ConstraintSet table, what you can find below of the above screens, select the view_background_gray and from the Attributes pane change the alpha from 1 to 0.

Similarly, change the alpha of view_background_blue from 0 to 1.

Next, select the iv_cloud_white ImageView. From its attributes remove the horizontal and the vertical bias lines. You can do it easyily in the right Attributes pane.

Then remove it’s right to right and the left ot left alignments.

Finally add the left to right alignment with value of parent. You can do in the desing mode if you click in the Attributes pane on the plus icon.

The result is that, the ImageView gonna be out from the screen at the right side.

The last change on the end ConstraintSet is to modify the attributes of the iv_cloud_grey ImageView as well. So, remove also the bias lines and the left to left – right to right constraints. Thenafter add the right to left constraint with the values of parent.

The Transition

The last thing what we have to set before the first run of the app, is to set the click event.

This click event will start the transition. We can add it to the Transition by clicking on it. You can open it if you click on the arrow which connects the start and the end ConstraintSets.

The MotionScene

Thenafter from the Attributes pane, in the OnClick part click on the + icon and add the below attributes with their values.

  • clickActioin -> toggle
  • targetId -> @id/iv_cloud_grey

The XML code of the MotionScene

If you are stucked, then just copy the below code into the activity_main_scene.xml file, what you can find in the res > xml folders.

<?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:constraintSetEnd="@+id/end"
        motion:constraintSetStart="@id/start"
        motion:duration="1000">
       <KeyFrameSet>
       </KeyFrameSet>
        <OnClick motion:clickAction="toggle"
            motion:targetId="@id/iv_cloud_grey" />
    </Transition>

    <ConstraintSet android:id="@+id/start"/>

    <ConstraintSet android:id="@+id/end">
        <Constraint
            android:id="@+id/view_background_gray"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:alpha="0" />
        <Constraint
            android:id="@+id/view_background_blue"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:alpha="1" />
        <Constraint
            android:id="@+id/iv_cloud_white"
            android:elevation="1dp"
            android:layout_width="200dp"
            android:layout_height="200dp"
            motion:layout_constraintBottom_toBottomOf="parent"
            motion:layout_constraintTop_toTopOf="parent"
            motion:layout_constraintLeft_toRightOf="parent" />
        <Constraint
            android:id="@+id/iv_cloud_grey"
            android:layout_width="150dp"
            android:layout_height="150dp"
            motion:layout_constraintBottom_toBottomOf="parent"
            motion:layout_constraintTop_toTopOf="parent"
            motion:layout_constraintRight_toLeftOf="parent" />
    </ConstraintSet>
</MotionScene>
Enter fullscreen mode Exit fullscreen mode

Run the app

Now its time to test the app. Connect your real device or start an emulator and run the app.

When it is loaded, then click on the clouds. The animation needs to run as you can see on this picture.

The end ConstraintSet

Step 6 - The Transition listener

In the last step of this tutorial we are going to implement the Transition listener. Using this listener we can add some actions to the start / end transitions and of course we can specify actions during the transition as well.

In our tutorial we are going to show a Toast message when the transition has been started and when it is finished.

First we have to add an id to the MotionLayout viewgroup in the activity_main.xml file. So open it from the res > layout folders and add the below line to the MotionLayout viewgroup.

android:id=“@+id/motionLayout”
Enter fullscreen mode Exit fullscreen mode

Next, open up the MainActivity::class file from the main source set.

We can use the setTransitionListener() method to add actions to the transition.

So, copy and paste the below line into the onCreate() method.

val motionLayout = findViewById(R.id.motionLayout)

motionLayout.setTransitionListener(object : MotionLayout.TransitionListener {
    override fun onTransitionTrigger(p0: MotionLayout?, p1: Int, p2: Boolean, p3: Float) {
    }
    override fun onTransitionStarted(p0: MotionLayout?, p1: Int, p2: Int)
    {
        Toast.makeText(this@MainActivity, "onTransitionStarted", Toast.LENGTH_SHORT).show()
    }
    override fun onTransitionChange(p0: MotionLayout?, p1: Int, p2: Int, p3: Float) {
    }
    override fun onTransitionCompleted(p0: MotionLayout?, p1: Int)
    {
        Toast.makeText(this@MainActivity, "onTransitionCompleted", Toast.LENGTH_SHORT).show()
    }
})
Enter fullscreen mode Exit fullscreen mode

First in the code we have to find the view of the MotionLayout. Thenafter we use its setTransitionListener() method.

As you can see, it has 4 methods. From them we are going to use only 2, So, we have added a Toast to the onTransitionStarted() and onTransitionCompleted() methods.

Run the app

Run again the app. When you start the transition and when it is finished, then you will have a Toast message on the screen.

Congratulations! 😎
Enter fullscreen mode Exit fullscreen mode

You just created a cool animation, what maybe you can use in your next app. 😊

Run the app

The source code is available on GitHub, check it out and download it using the below link.

GitHub

Android WeatherApp course

Did you like this short tutorial, then check out my Android WeatherApp course as well.

More Android tutorials

If you would like to do more Android tutorials like this, then visit my website:
Inspire Coding

Questions

I hope the description was understandable and clear. But, if you have still questions, then leave me comments below! 😉

Have a nice a day! 🙂

Top comments (0)