How we integrated Material Motion with Transforming Material
Motion plays a key role in bringing material design to life. Material uses motion to educate the user about hierarchy, guide focus through the experience, and even add delight in sometimes unexpected places. This year at Google I/O 2016, the material design team has revamped the Motion guidelines to include detailed guidance on all things motion, from basic duration and easing curves suggestions to natural surface transformations and intricate choreography of moving elements. We were inspired by John Schlemmer’s session at Google I/O 2016.
Last year, Android introduced this Shared Element Transition in which two screens shares some common asset which we can animate between them. This works on Lollipop and above and we will have to use backward compatible APIs so that it doesn’t crash in earlier versions. It seems that this task is huge but turns out that in most of the cases it would be very simple to implement. A few line of code changes and Voila! you would be seeing an amazing animation.
Sadly, our case in PregBuddy didn’t fall in one of these easy categories which gave us the motivation to write this post.
The Easy Part
First, let us explore the straightforward way in which simple code would bring amazing results. Let us assume there is a title text which is common in the two screens.
I hope you will already be having a styles-v21.xml file. To begin with, we need to enable windowContentTransitions property in this file. Having done this, create a string resource which we can use for both the TextViews.
Now in both the activities we will have to set the transitionName property to the above-created string resource:
Now comes the last bit. While starting the second activity, we can send these bundle options to create a beautiful animation.
Android takes care of the return animation on it’s own. In case you want to see the return animation on pressing home button ( the back button there in the Action Bar ), we can call supportFinishAfterTransition() instead of finish().
And, it’s done! See, it was that easy. Now let’s talk about the challenging part.
We at PregBuddy were using Glide for image loading. As you might have got it already, in our case the shared element is an image. We were using a couple of image transformations like fitCenter and CenterCrop to make our fetched image fit in the ImageView. Also, the dimensions of the images in both the screens were different. One has dimensions of a square and another rectangle. As a result, when we did all the things mentioned in the easy part, it was working except for a bug. The first image would animate to the second screen but it would apply the transformations afterward which looked very bad. In case there is difficulty in understanding it, here is a demo of the same.
A quick Google search will bring you to this article. This suggests you postpone the transition until the final matrix in the second activity is calculated. After trying this, we understood that it was not a feasible solution in our case as it took quite some time to fetch and apply the transformations. It was making the entire experience very sluggish. It might work for you, so don’t just ignore this in case you are stuck on a similar thing!
It was just then that Fresco, Facebook’s library for loading images, updated their transition set to include custom transformations as well during scaling. We just need to add the following lines to the Second Activity.
Yes, we had to change the Image Library to Fresco but now the animation is very smooth. There has been a lot of research which has gone behind material design and motion. It makes the entire app experience delightful by providing guided focus and fluidity.
Here is how our application look like with transforming material motion.
Here is how our application look like without transforming material motion.
If you are eager to know more about Material Motion, please visit their website and go through this I/O 2016 session on Discover the expanded Material Design motion guidelines.