Tutorial on Shared Element Transitions in Android Apps
- 6029 views
- 4 min
- Oct 29, 2019
In this article, we show you how to use the Navigation component with a transition animation and how to simplify this combination using Data Binding. When you learn how to use these technologies, standard transitions between screens in your app will no longer be boring.
Let’s start with a simple example and create an animated transfer of a regular view from one screen to another.
Simple example of a transition animation
To create such an effect, we need to assign android:transitionName to the view that will move between screens:
For convenience, we recommend creating a separate file with string-based resources where all transaction names will be stored.
Now it’s time to get to the main point ‒ transferring data about the animated view to the next screen. When we call the navigate method of the NavController, in addition to the NavDirections direction, we also need to pass navigatorExtras, which will contain all the necessary data about the animation:
Now we need to define the animation on the second screen. For that, we need to write the following code in the onCreate method of our fragment:
Our animation is ready. But what if we want to animate a lot of views? In this case, navigatorExtras will become too bulky. Kotlin extensions can help us. Let’s create an extension to make our code cleaner and simpler:
Now everything looks much better. You can also list all the views in an array, then go through it in a cycle and fill in navigatorExtras. You can write an extension for this if you want.
In some applications, you may also need to animate RecyclerView. Let’s take a look at how we can do that.
To animate a chosen element from the list, we need to specify a unique identifier for it in the transaction name. Let’s suppose each element contains a user model with an identifier. We’ll use this identifier in our animation. Then we’ll create a string resource with support for argument formatting.
It’s time to apply the created string resource with argument to our view and pass the user ID to this view. This is where the Data Binding library is going to help us: we just pass the user model to the layout, and then with the help of binders, we set everything we need.
Let’s set up the second screen. We need to pass the selected user as an argument. We’ll be using the Safe Args plugin for this purpose.
When the second screen has received the user, we need to pass this identifier as an argument to the transaction name for our view and enable the transition animation for this fragment.
That’s it! Our animation is ready. But when we return to the previous screen, there’s no animation. That’s because at the moment, the fragment has recreated the view and our list hasn’t initialized the elements yet. To make the animation work, we need to stop it till the list is rendered. And to do this, we need to create a new extension function:
Now our animation works in both directions.
Let’s move on to the most complex example, where we’ll use ViewPager.
At first, we need to prepare a screen with a list of images and a gallery screen. Then we need to apply the approach we used in the previous example. But for the correct display, we have to apply our own animation for the gallery screen.
We need to wait until the image in the gallery loads so the animation displays correctly. And here’s the trick we need to do that:
We’ll be using OnImageReadyListener to load the image, and we’ll postpone the animation until the image is loaded or a loading error occurs.
Now we can see that when we change the start page and go back, the animation doesn’t work properly. We’re about to fix that. To do so, we need to change the position of the returned item. The setEnterSharedElementCallback and setExitSharedElementCallback listeners will help us here.
Now it’s time to work with the gallery fragment. We need to implement a setEnterSharedElementCallback to animate the transaction. In this callback, we replace the original View with the View we chose in the gallery. To do that, let’s find this View in our ViewPager.
It’s very important to save the current position of our ViewPager. To do that, we’ll use Activity or the shared ViewModel. Now we’ll implement setEnterSharedElementCallback on the list screen, on which we need to repeat a similar operation.
That’s it! We’ve got the correct animation.
Check out the source code for this tutorial and don’t hesitate to start a conversation below if you have any questions. Subscribe to our blog to get more useful tutorials from us!
Subscribe via email and know it all first!