Playing with Material Design Transitions ✨

How to make material design transitions between two screens?

Philippe BOISNEY
ProAndroidDev

--

When you build an Android app, user experience is something that really matters. However, animations & transitions can really be a pain to implement in Android.

In this article, I will share with you my feelings about the implementation of this animation between two screens, called in Material Design a “Hierarchical transition” :

Hierarchical transition ❤️

Resources:

  • 📱 You can install the final APK implementing this transition at this link.
  • 💻 You can find all the code source in this repository.

What Do I Need For Such A Transition?

First, in order to implement this transition, I needed to know about some concepts :

  • Transition: A Transition holds information about animations that will be run on its targets during a scene change (for example when you go to screen B to screen A).
  • 🔗 Shared Element: A Shared Element is a View that will be animated and shared between two screens.
  • 🧸 Animated Vector Drawable: The AnimatedVectorDrawable class lets you animate the properties of a vector drawable, such as rotating it or changing the path data to morph it into a different image.

🔗 Identify The Shared Elements

The first thing I needed to do was to identify what will be the View shared through the two screens (so I can animate them properly during the transition) :

Views shared between the two screens

I identified 4 View that will be shared between the two screens :

Then, I set for each of those views, a unique transitionName value:

Example of setting “transitionName” value

Finally, I had to tell Android that, when it will launch the Intent of the second screen, it must know and care about those shared elements :

Launching second activity with shared elements.

Edit: In order to handle this issue (on some devices, the navigation bar is blinking when the transition starts), I created this convenient method that I use instead of ActivityOptionsCompat.makeSceneTransitionAnimation :

🧸 Identify the Animated Vector Drawable

Well, this part is pretty simple because I had to identify which icons are animated. In our example, we have 4 icons animated :

Preview of the animated icons

Great, the 4 animated icons were spotted! 🔍

Now, I had to convert each icon (PNG format) into an Animated Vector Drawable (XML format). In order to realize that, I used the awesome tool created by Alex Lockwood called Shape Shifter.

🔦 By the way, I created a full article that explains how you can create easily such of animated icons with Shape Shifter and Sketch.

All the AVD I created for this example are located in the project into the resource folder drawable-v21. You are totally free to reuse it in your own projects.

Once the AVD were created, I had to animate all the thing together through some transitions.

✨ Identify The Transitions

Complete transitions in slow motion (to better understand/visualize each one) 🐌

That’s the most interesting part. First, it’s important to differentiate two kinds of transition :

  • The one for the shared element views
  • The one for the other views (not shared)
styles.xml of the second screen

As you can see in this style, I set the two kinds of Transition with the XML properties :

  • windowSharedElementEnterTransition and windowSharedElementReturnTransition for the transitions that affect directly the shared element.
  • windowEnterTransition and windowReturnTransition for the transitions that affect the other views of the screen.

Shared Element Transitions

For example, let’s take a look at the activity_detail_s_e_enter.xml transitions file :

As you can see, this transitions file is responsible for declaring and triggering some transitions on our 4 Shared Elements that I defined earlier :

  • ChangeBounds: Android native transition. This transition captures the layout bounds of target views before and after the scene change and animates those changes during the transition.
  • FabAnimatableTransition: Custom transition. Based on Nick Butcher’s Plaid transition, it triggers AVD animation on the FAB view.
  • BottomAppBarAnimatableTransition: Custom transition. Same behavior of the previous transition, except it’s for the BottomAppBar.
  • FadeTransition: Custom transition. This transition will fade in/out the background view depending on a start and end alpha values.
The transition that will start the AVD animation.

However, you have may notice that both FabAnimatableTransition and BottomAppBarAnimatableTransition are subclasses of BaseForcedTransition.

Why? 🤨

I literally spent one day on it and I was finally saved by this SO answer (thanks Jinyan Cao 🙏).

Actually, during a scene transition, the framework will not trigger the createAnimator() (where our AVD are supposed to be started) if the starting and ending states for the transitioning views are the same.

That seems legit but not obvious to me.

Indeed, the FAB and BottomAppBar states are not changing during the transition… 😩

Well, that part was tough but instructive.

Normal transitions

Now that the shared elements are properly animated, I had to take a look at the file responsible for declaring and triggering some transitions on the remaining views :

As you can see in this file, I have excluded all the shared elements of this transition set and applied those following transitions to the remaining views :

  • Slide: Android native transition. This transition tracks changes to the visibility of target views in the start and end scenes and moves views in or out from one of the edges of the scene.
  • Fade: Android native transition. This transition tracks changes to the visibility of target views in the start and end scenes and fades views in or out when they become visible or non-visible.

Finally, I repeated those actions to the two screens to be able to reproduce the desired Material Design “Hierarchical Transition”… ❤

I really enjoyed playing with the Android Transition framework, especially because I barely had to modify the controllers (fragment/activity): everything can be done through XML files! #KeepOurControllersLight

Despite the fact that sometimes the transitions can be very long to implement due mainly to the complexity of our layouts and the necessity of perfect synchronization of each one of the animations, I totally approve the necessity to make our apps UX more Material Design.

--

--