Playing with Material Design Transitions ✨
How to make material design transitions between two screens?

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” :

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) :

I identified 4 View
that will be shared between the two screens :
- The Floating Action Button
- The Bottom App Bar
- The background View of the RecyclerView item
- The ImageView representing the user’s avatar
Then, I set for each of those views, a unique 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 :
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 :

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
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)
As you can see in this style, I set the two kinds of Transition
with the XML properties :
windowSharedElementEnterTransition
andwindowSharedElementReturnTransition
for the transitions that affect directly the shared element.windowEnterTransition
andwindowReturnTransition
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.
However, you have may notice that both FabAnimatableTransition
and BottomAppBarAnimatableTransition
are subclasses of BaseForcedTransition
.
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.