Material Motion With MDC

Karishma Agrawal
The Startup
Published in
6 min readJan 4, 2021

--

Motion helps make a UI expressive and easy to use.

Principles

Motion helps orient users by showing how elements in a transition are related.

It creates a personality for your app.

The Material motion system, recently released as part of the MDC-Android library (v 1.2.0), contains common transitions into a group of simple patterns for a smoother, more understandable user experience. Material motion currently includes four transitions:

I’ll try to explain each step by step in an app. So we can understand how to use these components when moving from activity or fragment or views for a better user experience.

Now the main concern is how to select a transition pattern according to your need among all these.

Selecting a pattern

Consider the following when determining which transition pattern is appropriate for a given use case:

Persistent containers

Is a persistent container part of the transition?

UI elements in a sequence are categorized as outgoing, incoming, or persistent.

  • Outgoing — elements exit the screen
  • Incoming — elements enter the screen
  • Persistent — elements start and end on the screen

Containers are shapes used to represent enclosed areas, such as buttons, lists, card surfaces. If there’s a container that’s a persistent element in the transition, choose the container transform pattern.

Relationships

Is there a spatial(elements in a vertical or horizontal layout) or navigational relationship(moving between peers or between levels in an app) between UI elements?

If a spatial or navigational relationship exists between elements, choose the shared axis pattern.

When a relationship between elements is insignificant or does not exist, the fade through the pattern is better suited.

Entering and exiting

Does a UI element enter or exit the screen?

Oftentimes a UI element simply needs to enter or exit the screen. For entering or exiting elements, the fade pattern is best suited.

Read the below article to understand various types of fade animation.

We are creating an email app, in which you can see the list of emails, see the full email by clicking on an item, search email, send a reply or forward the mail.

AppSetup : Add material design library support.

Basic understanding of the project:

  1. HomeFragment first screen shows list of emails
  2. EmailAdapter used to show email list in the home fragment
  3. Using the nav graph to move between views.
  4. EmailFragment displays a single, full email

In the above video we can see a list of emails on the main screen and when we click on any item it opens a full email view. Now because some part of the email is common in both the screen like title and user image and message, that means we can use shared transition. We can use Container transform according to our prev read.

Container Transform transition

A container transform in the MDC-Android library is called a MaterialContainerTransform. By default, this Transition subclass operates as a shared element transition, meaning the Android Transition system is able to pick up two views in different layouts when marked with a transitionName.

By default, the Android Transition system will automatically reverse the enter transition when navigating back, if no return transition is set.

Let’s see step by step process for creating animation.

email_item_layout.xml : View holder item view of email list

android:transitionName="@{@string/email_card_transition_name(email.id)}"

DO this line change in MaterialCardView.

The transition name takes in a string resource with a parameter. You need to use the id of each email to ensure each transitionName in our EmailFragment is unique.

You can access STRING and STYLES resources from the mentioned link.

Now because email item click takes us to full email view which is email fragment so we will add transition name in fragment_email as well.

fragment_email.xml :

android:transitionName="@string/email_card_detail_transition_name"

Add above line in MaterialCardView, now because of adding transition name in both files, the system will know what is start and endpoint of shared transition.

In shared transition we pass the elements while calling the other activity same here we need to pass elements from HomeFragment on click of an email.

HomeFragment.kt

Add the above code , on click of an email.

I am doing it through the Navigation graph , if you want to use bundle while fragment transaction, you can do that.

Now we need to handle the shared elements in the receiving fragment which is EmailFragment, where we will create an instance of MaterialContainerTransform in the onCreate method.

EmailFragment.kt

nav_host_fragment is resource id for fragment email which we have used in the main activity where we are adding this fragment.

  • drawingViewId: Set the id of the View whose overlay this transition will be added to.
  • duration: Sets the duration of this transition
  • scrimColor: Set the color to be drawn under the morphing container but within the bounds of the getDrawingViewId()
  • setAllContainerColor: Set the container color, the start container color and the end container color.

Now try to run the app. To show the data i am using some JSON files, you can use API or your own custom JSON. Right now just focus on how elements are shared between screens and how it improves the complete user experience. In the beginning, you can just start with 2 elements in your UI. I recommend you to practice it while reading otherwise you will not understand it.

Now things are looking Lil bit better when you click on the email and it expands in full view. But still, on click of back, there is no animation. One reason for this problem is when we are trying to show the animation list has not populated in its recycler view.

To fix this issue add two lines in on view created() of HomeFragment.

postponeEnterTransition()
view.doOnPreDraw { startPostponedEnterTransition() }

postPoneEnterTransition postpones the entering fragment transition until startPostponedEnterTransition() or executePendingTransactions() has been called.

This method gives the Fragment the ability to delay Fragment animations
until all data is loaded. Until then, the added, shown, and attached Fragments will be INVISIBLE and removed, hidden, and detached Fragments won't be have their Views removed. The transaction runs when all postponed added Fragments in the transaction have called
startPostponedEnterTransition().

This will resolve the issue, but let’s improve it more.

The issue of the email list disappearing is because when navigating to a new Fragment using the Navigation Component, the current Fragment is immediately removed and replaced with our new, incoming Fragment. To keep the email list visible even after being replaced, you can add an exit transition to HomeFragment.

HomeFragment.kt

exitTransition = MaterialElevationScale(false).apply {
duration = resources.getInteger(R.integer.reply_motion_duration_large).toLong()
}
reenterTransition = MaterialElevationScale(true).apply {
duration = resources.getInteger(R.integer.reply_motion_duration_large).toLong()
}

Add the above code in an email on the click method.

Next, in order to ensure that the MaterialElevationScale transition is applied to the home screen as a whole, instead of to each of the individual views in the hierarchy, mark the RecyclerView in fragment_home.xml as a transition group.

fragment_home.xml

this is the XML file fragment_home, in which we have a recycler view to show the list of emails. Here we will add

android:transitionGroup="true"

In a few lines we created a beautiful animation.

In my next article, i will cover the other 3 transitions.

Thank you for reading. 👏 I really hope you’ve found this article helpful. Your claps are really appreciated to help others find this article 😃 .

--

--

Karishma Agrawal
The Startup

Android Developer @Eventbrite | Wanted to be a writer so I write code now | Reader