Implementing activity and element transition animations in Android

Animations, if done correctly are always a delight to see. Especially when it comes to mobile apps—adding subtle animations here and there can help make your app stand out of the crowd and give it a more polished feel.

Google also gave animations the central stage when it unveiled its newest design language—Material Design—back in 2014!

In this blog post, I’ll be outlining how I implemented some simple yet effective animations in AfterShoot.

Do note that this blog post differs from an earlier one I wrote on Lottie:

While Lottie allows you to show pre-render animations in your apps, this blog post will outline how to animate a user action instead.

Here’s what the app looks like in its current state:

If you argue that the transition between the Activity is animated, just wait till the end of the post, and you’ll see what I mean.

About transition animations in Android

This post will outline 3 main types of animations:

  1. Activity Enter animation (when a user enters an activity)
  2. Activity Exit animation (when a user leaves an activity)
  3. Shared Element transition animation (when a user clicks on an element and opens a new activity containing that same element)

While there are certainly more possibilities with animations, we’ll limit ourselves to these three for the time being.

Implementing Activity transition animations

For the purpose of this blog post, enterAnimation refers to the animation to be shown when the user enters our Activity and the exitAnimation signals the animation to be shown when the user leaves our Activity.

Step 1: Define the type of animation to be shown

The Android SKD supports these activity transitions out of the box:

  • Explode — Moves views in or out from the center of the scene.
  • Slide — Moves views in or out from one of the edges of the scene.
  • Fade — Adds or removes a view from the scene by changing its opacity.

If you want, you can add a custom animation by making your own Kotlin class that extends the Visibility class.

You can play around with all the three animations before you decide which one you actually want. For AfterShoot, I went ahead with Explode as the Enter and Exit animation.

Step 2: Assign the animations to your Activity’s Window

To assign animations to your Activity’s Window, in the Activity’s onCreate() method and before setContentView() is called, we need to add the following lines of code:

class ImageActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // make sure to do this before setContentView or else the app will crash
        with(window) {
            requestFeature(Window.FEATURE_CONTENT_TRANSITIONS)
            // set set the transition to be shown when the user enters this activity
            enterTransition = Explode()
            // set the transition to be shown when the user leaves this activity
            exitTransition = Explode()
        }
        setContentView(R.layout.activity_image)
        ...
    }
    ...
}

Do this in all the activities that you want to animate.

Step 3: Start the Activity with the animation

Once the animations have been defined, starting the app right away won’t show you any animations. Instead, we have to start the Activity with the appropriate flag.

In the code snippet above, this is the instance of the Activity where you are starting the animation from (here it’s the MainActivity.

Step 4: Specify the duration of the animation

In case you want to play around with the duration for which the animation is shown, you can tweak this value as follows:

class ImageActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        with(window) {
            requestFeature(Window.FEATURE_CONTENT_TRANSITIONS)
            exitTransition = Explode()
            enterTransition = Explode()

            // shows the transition for 2 seconds
            exitTransition.duration = 2000
        
        }
        ...
    }
    ...
}

By default, there’s no duration, as each animation has its own pre-specified value. Specifying a fixed duration will override the default value that was assigned to the animation.

And that’s it! Let’s now look at how to implement a shared element transition in the app.

Implementing shared element transitions

As the name suggests, a shared element transition is an animation shown when a common element (like an image or text) is shared across two activities. To outline what I mean, have a look at this GIF:

As you can see, the cover art is shared between the first and the second screen and is animated using the shared element transition.

Implementing these in an app is again extremely easy—let’s see how to do so.

Step 1: Add a common tag to the element that’s shared across Activities

The first step in implementing a shared element transition is to identify the views that are shared across two different Activities/Fragments.

For example, in AfterShoot, the image in the RecyclerView and the image in the activity that appears after tapping the RecyclerView are shared:

So what I’ll do is add a tag to both of these ImageViews in their respective xml files. This is how it is done:

<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/ivGrid"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_margin="2dp"
    android:adjustViewBounds="true"
    android:transitionName="image" />
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.github.piasy.biv.view.BigImageView
        android:id="@+id/imageView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:transitionName="image"
        app:failureImage="@drawable/ic_baseline_error"
        app:failureImageInitScaleType="center"
        app:initScaleType="fitXY"
        app:optimizeDisplay="true" />

</androidx.constraintlayout.widget.ConstraintLayout>

Notice the android:transitionName attribute that’s common in both the ImageView in the first gist and the BigImageView in the second gist.

Step 2: Start the Activity with the shared element transition

Once you’ve defined the transitionName attribute on your views, the next step is to let the system know that we plan to implement a shared transition while starting the app. This can be done as follows:

private fun showImage(uri: Uri, holder: ImageHolder) {
        val intent = Intent(context, ImageActivity::class.jaba)
        
        // create an options object that defines the transition
        val options = ActivityOptions
                .makeSceneTransitionAnimation(activity, holder.itemView.ivGrid, "image")
        
        // start the activity with transition
        context.startActivity(intent, options.toBundle())
    }

The first parameter passed to makeSceneTransitionAnimation is an instance of the current Activity; the second is the shared view in the current activity, and the third parameter is the transitionName that’s shared with the View in the second activity.

Once you start the app, this is what the end result looks like:

As you can see, our images have a well-defined path they follow whenever the activity is started and finished.

Step 3: Transition with multiple views

In the case of multiple views being shared across activities, we can specify the views and names that are to be shared while making the options object as such

where imageView and textView are the shared widgets in the first activity and “image” and “text” are their transitionName respectively.

And that’s it! With a few simple steps, we were able to implement subtle yet effective animations in the app!

If you want to look at the source code for the contents covered in this blog post, you can find it here:

Thanks for reading! If you enjoyed this story, please click the 👏 button and share it to help others find it! Feel free to leave a comment 💬 below.

Have feedback? Let’s connect on Twitter.

Avatar photo

Fritz

Our team has been at the forefront of Artificial Intelligence and Machine Learning research for more than 15 years and we're using our collective intelligence to help others learn, understand and grow using these new technologies in ethical and sustainable ways.

Comments 2 Responses

  1. Webtoniq says:

    “Brilliant post on implementing activity and element transition animations in Android! Your clear explanations and practical examples have made a seemingly complex topic so much more accessible. Excited to incorporate these animations into my Android projects – thanks for the insightful guide!”

    1. Avatar photo Fritz says:

      You’re welcome 🙂

Leave a Reply

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