Meaningful Motion: Circular Reveal & Shared Elements

Jossi Wolf
Snapp Mobile
Published in
5 min readDec 28, 2017

This post was featured in Android Weekly’s #290 issue

Material Design brings us Material Motion and the Android Framework gives us the possibilities to implement it in our apps. In this post I will write about implementing a Google-Play-like circular reveal effect with shared elements.

Circular Reveal Transition in the Google Play Store (https://www.youtube.com/watch?v=B5hBViIzw5Y)

This post was heavily inspired by Antonis Tsagaris article My FAB brings all the boys to the yard, damn right and is specifically about implementing a circular reveal effect with shared elements and a CollapsingToolbarLayout .

Why Make The Effort?

Apart from the obvious (it really is pretty and smooth), it improves User Experience. Shared elements help the user keep track of what is happening on the screen and make opening a new screen less confusing.
Good UX is a key factor in your apps’ success.

The Implementation

Implementing a transition can be tricky to get started with, so let’s break it down and see what we need.

A circular reveal starts from a specific point, in our case it starts in the center of the view we want to reveal. We will start with a basic scrolling activity as generated by Android Studio. Now we will add a circle roughly in the center of the CollapsingToolbarLayout and also an ImageView that serves as background. There surely are many ways to create a colored circle, I modified a custom view from a library because I needed it to be dynamic.

Our app should now look like this. A little weird, but it’s worth it, just wait!

We have added a circle and have given it a transitionName . This name is used for shared elements in transitions. We will use this later when starting this activity.

The ImageView we added is hidden at the beginning, it is the view that will be revealed. It serves as background because hiding the CollapsingToolbarLayout doesn’t really look nice.

Now, we will add the circular reveal. Luckily, this is very easy as there is a method for this provided by the Android framework, ViewAnimationUtils#createCircularReveal . We only need to provide the center point, view to be revealed and the start and end radius.

But first, let’s take a look at how our starting activity looks.

For demonstration purposes, I added a RecyclerView with some items.

For the RecyclerView, I defined an onClickListener .

We create an Intent that will start SecondActivity . Before we actually start the other activity, we create the options to be used for the shared element transition. We add the view that should act as an shared element and its transition name (the one we defined earlier in the layout of SecondActivity ). Finally, we start the activity with the options. It looks like this:

The Big Reveal

Alright. Our circle is moving to a specific point and now we want to reveal our hidden background view. As I mentioned earlier, there is a method in the Android Framework for this:

createCircularReveal (target: View, 
centerX: Int,
centerY: Int,
startRadius: Float,
endRadius: Float): Animator

It is available on API 21+, but there is a backport for API 14+.

We’ve got the target, our ImageView . The reveal animation starts at (centerX|centerY) , which in our case we want to be the center of our circle.

We can use a Kotlin extension function (or not) — the math stays the same

Our start radius will be 0 and the end radius the width of our target view. The radius will increase throughout the animation.

We get the center of our circle (roundedImage) and create the animation. After that we set the duration to 400ms. I experimented a bit with this value and found something between 360ms and 400ms to be the smoothest.

Finally we make our ImageView that will be revealed by the animation visible and start the animation.

Now we can add a listener to our shared element transition and call our reveal function once the transition has ended.

Full DSL code for Kotlin here

This is what the transition and reveal look like now:

Pretty neat, isn’t it?

Making the transition “Material”

Real-world forces, like gravity, inspire an element’s movement along an arc rather than in a straight line.

Until now, our shared element is moving along a straight line — and you have to admit, it looks a bit unnatural. Let’s fix this!

We can create our own TransitionSet and use it. We can do this by creating a new XML file in our transitions resources folder. An arc motion TransitionSet can look like this:

We can now use this transition using TransitionSet and TransitionInflater .

We create a new TransitionSet , inflate our arc transition and add it to the set. We set the duration to 380 and use an AccelerateDecelerateInterpolator to influence how our shared element will behave. The AccelerateDecelerateInterpolator helps us to get a non-linear motion. Just like in the real word, where motion is rarely linear.

Exiting with grace

Of course, we also want to have the circular reveal effect reversed when exiting the activity.

It is pretty much the same as the enter transition, except for startRadius and endRadius from earlier being exchanged and hiding the ImageView instead of showing it.

We will also set the transition for exiting the activity:

We again create a TransitionSet , only this time we add a start delay of 200ms so the activity exit transition and reveal hide animation don’t completely overlap each other.

The final result

MinSDK?

The createCircularReveal method was introduced in API 21, but there is a library that backports the circular reveal.

There is also a library that implements shared element transitions on API 14+.

With those two libraries it should be possible to create a similar effect, although I haven’t tried it.

Conclusion

Implementing a specific transition or animation can be tricky to get started with, especially when it is not obvious how the animation works. It helps to break what you are trying to achieve down, for example by taking a recording and slowing it down.

With Android’s tools, once you have broken the animation down, it is possible to implement animations and material, meaningful motion in your app and improve your UX.

You can find the full source code here: https://github.com/jossiwolf/CircularRevealExample

Below are some links for reading on about animations, transitions and meaningful motion on Android.

Reading on

Thanks to Alberto Ballano and Kim Wiederhold for proof-reading and giving me feedback!

--

--

Jossi Wolf
Snapp Mobile

Software Engineer @Google working on Jetpack Compose. I like Kotlin, Animations and Rabbits! speakerdeck.com/jossiwolf