Twitter LogoFacebook Logo
Transition and Shared Element Transition Animations for the Navigation Component
[object Object]
By: King Wai Mark

Hello, in this video, I will be talking about animations for the Navigation Component.


I will show you how to add full page animations as well as shared element animations where we can animate individual views while transitioning.

If you are new to the Navigation Component, be sure to view the tutorial on the Navigation Component.

https://codeible.com/view/tutorial/9ebiqezy9ewNojdb3I81;title=Android%20-%20Navigation%20Component

To begin, create some destinations for the navigation component. Open the navigation graph.
Then click on the New Destination icon and add 2 new destinations.

Name the first one page 1 and the other page 2.

Image from Codeible.com

Lastly, add an action. 

Image from Codeible.com

Find an image you can use and drag the image file into the drawable folder under the resource directory.


In the Navigation graph, double click on the page 1 destination. This will automatically open the layout file for that particular destination.

Switch into the code view and change the layout from Frame to constraint.

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout  ...>


</androidx.constraintlayout.widget.ConstraintLayout>

Switch back to the design view and add an image view for the image you placed in your project. Add the constraints, set the width and height 200dp, and then set the scale type to center crop. 

Image from Codeible.com

Next, go back to the navigation graph and double click on the page 2 destination so we go directly to the layout file.

Switch into the code view and change the layout from frame to constraint as well.

Go back to the design view and add an image view with the image you chose in page 1.

Add the constraints, set the width to match the constraints and the height to 400dp, and then set the scale type of center crop.

Image from Codeible.com

Lastly, go into the page 1 fragment class file and add a reference to the image view.


Then add a on click listener to it and call the navigate method from the navigation controller.

We want it to navigate by using the action so we will pass in the id of the action instead of the destination.

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {

     View root = inflater.inflate(R.layout.fragment_page1, container, false);

     ImageView imageView = root.findViewById(R.id.imageView);

     imageView.setOnClickListener(
             new View.OnClickListener() {

                 @Override
                 public void onClick(View v) {

                        Navigation.findNavController(v).navigate(
                                R.id.action_page1_to_page2);
                 }

             }
        );

        return root;
}

If we run the application and click on the image, we should transition to page 2.

Adding Animations

To add animations, go to the navigation graph.


Click on the action that you want to add the animations to. Then put an animation file in the fields under the animations section of the attributes pane.

Image from Codeible.com

We can type anim and we will see some animations that were provided for us.

Image from Codeible.com

The enterAnim attribute is the animation for the destination that is entering the navigation host.

And the exitAnim attribute is the animation for the destination that is exiting the navigation host.

So, if we are going from page 1 to page 2, the enter animation will be applied to page 2 because it is entering the navigation host.

The exit animation will be applied to page 1 because it is exiting the navigation host during the transition.

We can use the default slide_in_left animation for the enter animation

And we can use the slide_out_right animation for the exit animation.

Image from Codeible.com

If we run the application, we will have a slide effect.

Custom Animations

Instead of using the predefined animations, we can also create own. 

In Android Studio, select the Android option from the dropdown menu so we see all the necessary files and directories for our project.

Right click on the resource folder and go to New > Android Resource File.

Image from Codeible.com

Give the file a name and change the resource type to Animation.

Image from Codeible.com

This will create an anim directory with our xml animation file inside.

Image from Codeible.com

With the animation xml file, we can create an animation to translate, scale, rotate, and change the opacity of the views.

First set the duration of this animation.

The duration attribute accepts a millisecond value. So If I want this animation to last 1 second, I would put 1000 since 1000 milliseconds is 1 second. 

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="1000">

</set>

Next, we can either to translate, scale, rotate, or change the opacity.

If I want to create a slide-in animation, I would use translate to move the views.

When something slides in, it can go from left to right. So I want to view to start at a position that is far enough that it is not visible in the screen.

I can put a numeric value like -1000 to place the view 1000 spaces to the left or I can do -100% and it will place the view on the left depending on the width of the view.

If the view is 500 pixels, -100% of that is -500 so it will place the view 500 pixels to the left. 

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="1000">

   <translate
        android:fromXDelta="-100%">
   </translate>

</set>

Then I want it to end up at 0 pixels.

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="1000">

   <translate
        android:fromXDelta="-100%"
        android:toXDelta="0">
   </translate>

</set>

With this, it will move the view from left to right in 1 second.

If we go back to our navigation graph and click on the action. We can replace the enter animation with the custom animation file.

Image from Codeible.com

If we run the application, it will move from left to right but at a slower pace.

Shared Element Transitions

Aside from full page animations, we can also apply animations to individual views in a layout.

There is a 3 step process.

First, we need to assign a name to match each view in the layout that we want to animate.

Second, we need to tell the navigation controller which views we want to use for the animation by providing the name that was given to the views.

And third, we need to set the type of animation we want to use for the views during the transitioning phase.

In our example, we have a small image view in page 1 and a larger image view in page 2.

Image from Codeible.com

If we want to animate it to gradually increase in size while transitioning, here is how we would do that.

Go back to the Navigation Graph. 

Double click on the page 1 destination to go to the layout file.

Give the image view a name, click on it and then search for the transitionName attribute in the attributes pane.

Image from Codeible.com

Next, go back to the Navigation Graph and double click on the page 2 destination.

Click on the image view and search for the transitionName attribute again. This time, put the same name you used for the image view in page 1. 

Image from Codeible.com

Now that we named the views we want to animate, we have to tell the Navigation Controller that we want to use the image views for the animation.

Go to the page 1 fragment class file.

Create an Extras object from the Fragment Navigator class.

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {

     View root = inflater.inflate(R.layout.fragment_page1, container, false);

     ImageView imageView = root.findViewById(R.id.imageView);

     imageView.setOnClickListener(
             new View.OnClickListener() {

                 @Override
                 public void onClick(View v) {

                        FragmentNavigator.Extras extras =
                                new FragmentNavigator.Extras.Builder()
                                .build();
                        Navigation.findNavController(v).navigate(
                                R.id.action_page1_to_page2);
                 }

             }
        );

        return root;
}

We use this object to tell the Navigation Controller which views we want to use during the animation.

Just before we call the build method to create the extras object, call the addSharedElement method and add the view that we want to animate. 

Pass in the image view reference and its transitionName.

FragmentNavigator.Extras extras =
                                new FragmentNavigator.Extras.Builder()
                                .addSharedElement(imageView, "my_image")
                                .build();

If you have more than 1 view that you are trying to animate, call the method multiple times to add them.


Next, add the extras object in the navigate method call. Put null, null, and then the extras object.

Navigation.findNavController(v).navigate(
                                R.id.action_page1_to_page2,
                                null,
                                null,
                                extras);

Lastly, set the animation you want to use for the view. 


Go to the page 2 fragment class file and call the setSharedElementEnterTransition method in the onCreateView method. Then pass in the ChangeBounds animation 

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {

     View root = inflater.inflate(R.layout.fragment_page2, container, false);

     setSharedElementEnterTransition(
                new ChangeBounds()
     );

     return root;
}

The ChangeBounds animation will detect the position, size, scale, and opacity of the views in both layouts and gradually change the values.

Now we are done. But as best practice, we should not have a full page transition animation with shared element transitions. 

Go to the navigation graph and remove the enter and exit animation form the action.

If we run the application and click on the image view, it will enlarge itself while transitioning to page 2.


Sign In