How to create activity transition animations on Android Lollipop

Android KitKat introduced the transition framework, which is a very convenient set of APIs for animating between different UI states in an application. The framework is built around scenes and transitions. A scene refers to a given UI state in an application (think of a scene like a ViewGroup, so the entire layout of an Activity can be a Scene, and also there can be multiple Scenes in a single Activity), while a transition is the animated change from one scene to another. Lollipop has taken transitions to a whole new level. The animations are easier to implement, and there are more powerful defaults now available to developers.

While this discussion will focus on transitions between two Activity classes, there are very similar methods for Fragments.

There are two distinct types of Activity transitions:

(1) Content transitions - which determine how the Activity's views enter or exit the scene.

(2) Shared Element transitions - which specify how elements are animated from a given start Activity (or Fragment) to another element in the specified end Activity (or Fragment).

Preparation

We will use the following convention. ActivityA and ActivityB are two separate Activities, and ActivityA starts ActivityB. ActivityA will be referred to as the start Activity, while Activity B will be called the end Activity.

The transitions API has methods to specify transitions for four different conditions.

  • Exiting A: This is the transition called when the app leaves the start Activity.
  • Entering B: This specifies the animation used when the app enters the end Activity.
  • Returning from B: This animation is run when the user leaves the end Activity, heading back to the start Activity (usually through pressing the back button).
  • Re-entering A: This animation is used when the app is back at the start Activity from the end Activity.

In the case where you do not specify a return transition, the enter transition would be used, and likewise, the re-enter transition defaults to the exit transition when not specified.

NOTE: The techniques discussed here are applicable to Android L devices (API level 21) and above only. These APIs were introduced in version 21 and are not available via the support libraries.

Setup

To enable transitions in your Android application, you should add the following to your application theme.

<resources>
    <style name="AppTheme" parent="android:Theme.Material">
        <!-- enable window content transitions -->
        <item name="android:windowContentTransitions">true</item> 

        <!-- enable overlap of transitions --> 
        <item name="android:windowAllowEnterTransitionOverlap">true</item> 
        <item name="android:windowAllowReturnTransitionOverlap">true</item>
    </style> 
</resources> 

Or add the following in code:

// inside your activity (if you did not enable transitions in your theme)
getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);

These are not necessary if your application uses one of the Material themes, where transitions is already enabled by default.

Content Transitions

Content transitions specify a given type of animation for the UI elements contained in an Activity when leaving or entering the Activity. There are three transition animations available in API 21.

  • Fade: Where the elements in the Activity gradually fade out of (or in to) view.
  • Explode: The UI elements move out of (in to) the center of the scene.
  • Slide: The UI elements all slide to (from) a specified screen edge.

To implement content transitions, it requires two steps:

  1. Define the required transition type in the onCreate method of the Activity.
  2. Add an API method indicating there are available transitions to the startActivity method.

To specify the required transition type for the start Activity (ActivityA):

        Transition exitTrans = new Explode();
        getWindow().setExitTransition(exitTrans);

        Transition reenterTrans = new Slide();
        getWindow().setReenterTransition(reenterTrans);

And for the end Activity (ActivityB):

        Transition enterTrans = new Explode();
        getWindow().setEnterTransition(enterTrans);

        Transition returnTrans = new Slide();
        getWindow().setReturnTransition(returnTrans);

The required API method indicating there are available transitions involves the ActivityOptions class as follows.

                ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(ActivityA.this);
                Intent intent = new Intent(ActivityA.this, ActivityB.class);
                startActivity(intent, options.toBundle());

The ActivityOptions class provides methods for building a bundle that can be used with the startActivity method to manage transitions between the activities. In this case, we call the makeSceneTransitionAnimation method with a single argument (the start Activity). Note that this is not needed in the end Activity. All four transition states (exit, enter, return, reenter) will be correctly handled with this.

Shared Element Transitions

This type of transition between activities occurs when both activities have a shared or similar UI widget. A shared element transition enables users to understand the flow of information between both Activities, and also guides the focus of users subliminally towards the shared element in the end Activity.

The method to implement shared element transitions is slightly different. First, we identify the shared UI element in both Activity xml files, and then we define transitionName in XML (which should be identical to both elements).

For example, in activity_a.xml, we have:

            <TextView
                android:id="@+id/blueTextView"
                android:text="@string/hello_world"
                android:layout_width="wrap_content"
                android:layout_height="150dp"
                android:layout_marginLeft="@dimen/default_margin"
                android:layout_marginRight="@dimen/default_margin"
                android:padding="@dimen/big_padding"
                android:transitionName="redView"
                android:background="@color/blue"/>

and in activity_b.xml, we have:

            <TextView
                android:id="@+id/redTextView"
                android:text="@string/hello_world"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginLeft="@dimen/default_margin"
                android:layout_marginRight="@dimen/default_margin"
                android:padding="@dimen/big_padding"
                android:transitionName="redView"
                android:background="@color/blue"/>

To specify a shared transition using these two elements, we use the following snippet.

ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(
                        ActivityB.this, fuchsiaTextView, "fuchsiaView");
                Intent intent = new Intent(ActivityB.this, ActivityC.class);
                startActivity(intent, options.toBundle());

For a shared element transition, the ActivityOptions.makeSceneTransitionAnimation method takes two additional parameters (the shared View in the current Activity, and the transitionName that's common to both Activities).

Multiple Shared Elements

It is worth mentioning that Shared View transitions are not limited to one shared view between both activities. You can have as many shared views as you want, and they don't even have to be of the same type of View. A TextView in the start Activity can morph into an ImageView in the end Activity. The sample project has a TextView in the start Activity transition into a Button in the end Activity. To animate multiple shared views, specify a new android.util.Pair object that contains the View in the current Activity, and the corresponding transitionName.

ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(
                        ActivityB.this, new Pair(fuchsiaTextView, "fuchsiaView"),
                        new Pair(redTextView, "redView"));
                Intent intent = new Intent(ActivityB.this, ActivityC.class);
                startActivity(intent, options.toBundle());

In the TransitionSamples project, there are three Activities (ActivityA, ActivityB and ActvityC). ActvityA uses content transitions when starting ActivityB, and ActivityB uses a single shared element transition for one instance while starting ActivityC, and two shared elements for another instance.

There are methods available for further customization of the transitions, including the length of the animation, direction of the device to slide to/fro (for Slide()), among others. Have fun experimenting with the APIs.

Subscribe to Xmodulo

Do you want to receive Linux FAQs, detailed tutorials and tips published at Xmodulo? Enter your email address below, and we will deliver our Linux posts straight to your email box, for free. Delivery powered by Google Feedburner.


Support Xmodulo

Did you find this tutorial helpful? Then please be generous and support Xmodulo!

The following two tabs change content below.

Obaro Ogbo

Obaro Ogbo is a software developer, who's always on the hunt for easy ways to solve complex problems. He enjoys the freedom offered by UNIX based systems (Linux and Android), and can be spotted peering at a screen creating, studying or enjoying different types of computer programs. He's currently exploring mobile app and game development. When away from technology, he's most probably sleeping or playing basketball.

Leave a comment

Your email address will not be published. Required fields are marked *