Learn Motion Layout in Android Using the Twitter Splash Screen

Clint Paul
Geek Culture
Published in
6 min readApr 3, 2021
Motion layout animation

Animations always fascinated me. The synchronized or not-so-synchronized movement of objects in a screen, along with its creator’s vision, will create a delightful experience. Applications with subtle animations are a joy to watch. I remember opening the same app again and again to see its wonderfully implemented animations. Being said that, implementing animations in an Android app was not always easy. Whenever I put my hands on implementing animations in an app, I realized that I have to deal with lots of boilerplate code, messy XML files, and an unorganized structure.

Android introduced Motion layout back in 2018 to solve the many challenging issues of implementing animations. The advantage is that Motion layout is a subclass of Constraint layout and builds upon its rich layout capabilities. So, today I’m going to share my thoughts about Motion layout in Android. I’m also going to create the ever-famous twitter splash screen ( Even though there are many other blogs on the same ).

Let’s start building our project

Convert your Constraint layout to Motion Layout

  1. Create a new project in Android studio. I’m using Android studio 4.1.1 and Kotlin.
  2. Go to the XML file of the MainActivity.kt class and click on the Design tab.
  3. Right-click on the project pane, and there you can see several options, including ‘Convert to motion layout.’ Click on it.
  4. 🥳🥳🥳 Great work. You just converted your normal layout to a Motion Layout.
Right click on the project pane

Add a background color and a Twitter logo

  1. Give a new background color ( Twitter like ) to the parent layout. (#03A9F4 )
  2. Download a twitter logo and add it in your layout as an ImageView.

Your main layout will look like this now.

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"
android:background="#03A9F4"
app:layoutDescription="@xml/activity_main_scene"
tools:context=".MainActivity">

<ImageView
android:id="@+id/imageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/ic_twitter" />
</androidx.constraintlayout.motion.widget.MotionLayout>

3. Run the app and check if everything working correctly.

Twitter Splash screen without animation

Now, think for a moment about how the Twitter splash screen is working. The Twitter logo will be in its resting position at first. Then it will scale down to a few seconds, then it will come back to its original position, and then it scales up to the full screen. Please check the video below for reference.

Twitter splash screen

What is Motion Scene?

A Motion scene is an XML file that contains all of the motion descriptions for the corresponding layout. In our case, whatever animations we implement for our Twitter splash screen will be written in the motion scene XML file.

Let’s examine activity_main_scene and it’s main attributes.

<?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>
</Transition>

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

<ConstraintSet android:id="@+id/end">
</ConstraintSet>
</MotionScene>

Transition

When you think about the transition, it’s a movement from one end to the other. During that movement, you can add certain modifications like the duration of motion, the type of animation, define the start and end constraint sets, etc.

ConstraintSet

ConstraintSet helps us to pinpoint each item in a layout and then add various constraints to this item. In our case, we have to add constraints for our Twitter logo. If you have more than one view present, you can add more Constraint according to your need.

I’m going to add only start ConstraintSet for the time being. These endpoints are centered vertically (via app:layout_constraintTop_toTopOf="parent" and app:layout_constraintBottom_toBottomOf="parent"). Horizontally, the endpoints are at the far left and right sides of the screen.

<ConstraintSet android:id="@+id/start">
<Constraint
android:id="@+id/imageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
motion:layout_constraintBottom_toBottomOf="parent"
motion:layout_constraintEnd_toEndOf="parent"
motion:layout_constraintStart_toStartOf="parent"
motion:layout_constraintTop_toTopOf="parent" />
</ConstraintSet>

KeyFrameSet

Let’s imagine the course of the transition is between 1 to 100 ( start to end ). What if we want to make some changes to the view during this period. These checkpoints are called KeyFrameSet. It gives us a few more attributes to gain complete control of the view during this transition. Like,

  • KeyAttribute: Specifies view attributes at a specific moment during the motion sequence. In our case, we will have to scale the Twitter logo up and down during its transition. KeyAttribute will help us to achieve that.
  • framePosition: Here, we can specify the position we need to make changes to the KeyFrame.
  • motionTarget: It specifies which view is affected by the KeyFrameSet. In our case, it will the Twitter logo ( ImageView ).

Now, let’s add the code inside the KeyFrameSet and analyze the working.

<KeyFrameSet>
<KeyAttribute
android:scaleX="1"
android:scaleX="1"
motion:framePosition="10"
motion:motionTarget="@+id/imageView" />
<KeyAttribute
android:scaleX="0.5"
android:scaleY="0.5"
motion:framePosition="20"
motion:motionTarget="@+id/imageView" />

<KeyAttribute
android:scaleX="0.5"
android:scaleY="0.5"
motion:framePosition="30"
motion:motionTarget="@+id/imageView" />

<KeyAttribute
android:scaleX="50"
android:scaleY="50"
motion:framePosition="100"
motion:motionTarget="@+id/imageView" />


</KeyFrameSet>
  • Remember what I said earlier? The Twitter logo will be in its resting position at first? Yes. Since it is in a resting position, let’s give the value 1 for scaleX and scaleY ( I think it’s self-explanatory what are scaleX and scaleY ). And since it is continuously moving during this period, let’s give the framePosition a value of 10. And the motionTarget will be the Twitter logo, i.e., imageView.
        <KeyAttribute
android:scaleX="1"
android:scaleY="1"
motion:framePosition="10"
motion:motionTarget="@+id/imageView" />
  • Next, we must scale down the Twitter logo to some extent for a certain period. So, I have decided to give a value of 0.5 to scaleX and scaleY and framePosition as 20 and 30. The motionTarget will be the same Twitter logo.
<KeyAttribute
android:scaleX="0.5"
android:scaleY="0.5"
motion:framePosition="20"
motion:motionTarget="@+id/imageView" />

<KeyAttribute
android:scaleX="0.5"
android:scaleY="0.5"
motion:framePosition="30"
motion:motionTarget="@+id/imageView" />
  • Finally, we need to scale up the Twitter logo to the full-screen. Naturally, if we need to scale up a view to its full screen, then the scaleX and scaleY values will be large in size. So, I have decided to give scaleX and scaleY a value of 50. And the framePosition will be 100 because the transition must have run its course.
        <KeyAttribute
android:scaleX="50"
android:scaleY="50"
motion:framePosition="100"
motion:motionTarget="@+id/imageView" />

Don’t forget to add the line motion:autoTransition=”animateToEnd” inside the “Transition” attribute. It helps for the automatic transition from one state to another. Here, we are using “animateToEnd.”

Complete activity_main_scene.xml code.

<?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:autoTransition="animateToEnd"
motion:constraintSetEnd="@+id/end"
motion:constraintSetStart="@id/start"
motion:duration="1000">
<KeyFrameSet>
<KeyFrameSet>
<KeyAttribute
android:scaleX="1"
android:scaleY="1"
motion:framePosition="10"
motion:motionTarget="@+id/imageView" />
<KeyAttribute
android:scaleX="0.5"
android:scaleY="0.5"
motion:framePosition="20"
motion:motionTarget="@+id/imageView" />

<KeyAttribute
android:scaleX="0.5"
android:scaleY="0.5"
motion:framePosition="30"
motion:motionTarget="@+id/imageView" />

<KeyAttribute
android:scaleX="50"
android:scaleY="50"
motion:framePosition="100"
motion:motionTarget="@+id/imageView" />


</KeyFrameSet>
</KeyFrameSet>
</Transition>

<ConstraintSet android:id="@+id/start">
<Constraint
android:id="@+id/imageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
motion:layout_constraintBottom_toBottomOf="parent"
motion:layout_constraintEnd_toEndOf="parent"
motion:layout_constraintStart_toStartOf="parent"
motion:layout_constraintTop_toTopOf="parent" />
</ConstraintSet>

<ConstraintSet android:id="@+id/end"></ConstraintSet>
</MotionScene>

Now, run the app and check if everything is working according to the plan.

What I have shared with you is just the tip of the iceberg. Motion Layout can do much more. That’s why developers are curious to see how Motion layout will integrate with Jetpack compose. Many Android developers are so fond of this tool that they don’t want to lose it in the transition. I hope the Android team will find a way to efficiently gel Jetpack compose and Motion layout.

You can find the complete project here.

Follow me on Twitter for Android/Kotlin related news.

Article was originally posted at clintpauldev.com

Additional resources

For more information on MotionLayout, see the following links:

--

--

Clint Paul
Geek Culture

Software Engineer @ShareChat. I love to read and write.