Using Circular Reveal animation to create a beautiful material sharing card

With more and more android phones running on lollipop (API level 21+), it becomes essential for android developers to develop applications which takes full advantage of Material Design. While I was going through UI designs on Dribbble, I came across this post by Benjamin Berger which caught my eye. The entire code base is on GitHub. Optionally you could download APK from here.

Material Sharing Card by Benjamin Berger

BUILDING THE USER INTERFACE (UI)

Setting up the UI is a fairly simple challenge. It makes use of 4 basic views

The parent layout is a CardView, which has ImageView on top, TextView's on the bottom and a FAB button in between. Clicking on the FAB button produces Circular Reveal animation.

LAYOUT IN EASY STEPS

Layout is pretty straight forward. You have a CardView, which has 3 vertical views. So it's easy to use LinearLayout with layout_orientation="horizontal". The problem with this layout is, it is hard to position the FAB button in between the two Views.

So the solution to this problem is to use RelativeLayout. RelativeLayout can be used to correctly position FAB button. And this is done using just 3 - 4 lines of XML code.

400: Invalid request

The idea here is, I'm setting the FAB button below ImageView, then I'm shifting the FAB 28dp up. So now it stands directly between ImageView and the bottom View. Finally I'm setting a right margin of 16dp. So the outcome is this

FAB Button

CIRCULAR REVEAL INTO ACTION

This is the challenging part. Till now I have an ImageView, on which I want to have the circular reveal animation which has twitter logo's color along with three buttons inside. For this I put the ImageView inside a FrameLayout.

So the FrameLayout now has two direct children, an ImageView and a Linearlayout whose height and width are same as that of ImageView [Done programmatically]. The LinearLayout has a background color of twitter blue, and has three buttons inside. Initially the LinearLayout's visibility is set to gone.

Now I set circular reveal animation to the LinearLayout which is fired when I click on the FAB button. According to android documentation

Reveal animations provide users visual continuity when you show or hide a group of UI elements. The ViewAnimationUtils.createCircularReveal() method enables you to animate a clipping circle to reveal or hide a view.

Code snippet from https://developer.android.com/training/material/animations.html

400: Invalid request

Note this line

Animator anim = ViewAnimationUtils.createCircularReveal
    (view, centerX, centerY, startRadius, endRadius);

/*
createCircularReveal(View view, int centerX, int centerY, float startRadius, float endRadius)
*/

Here argument view is the element you want to animate, which in my case is LinearLayout. centerX and centerY are the starting points for the animation. Above code sets the starting point to be the center of the view, but in my case is the bottom right hand corner. So I set

int centerX = imageView.getRight();
int centerY = imageView.getBottom();

The forth argument startRadius is initially 0.

The endRadius is a bit tricky part. endRadius the radius or the extent to which circular reveal animation is to be shown. In my case is the diagonal length.

Radius

The diagonal of the rectangle is equivalent to finding the length of the hypotenuse of a right triangle. Thanks to some high school math, I can get the length of the diagonal by using Pythagorean theorem.

int endRadius = (int) Math
    .hypot(imageView.getWidth(), imageView.getHeight());

Luckly Java has an inbuilt method in Math class for finding hypotenuse.

Finally when I click on the FAB button, I change the visibility of LinearLayout to VISIBLE, and call start() method on the animation object. The reverse animation uses the same logic, which you could check here.

TAKING IT A BIT FURTHER

If you look closely on the animation which I'm trying to achive, you can see that immediately after LinearLayout is visible, the buttons are not shown. There is a delay like 100 - 200 milli seconds. So inorder to achieve that you can do the following inside the LinearLayout.

400: Invalid request

Nothing complicated here. There are three buttons inside the LinearLayout. To bring about a fading in effect on the button, we are using alpha animation which is provided by android.

400: Invalid request

fromAlpha="0.0" means the view's opacity is initially 0, and toAlpha="1.0" means final opacity is 100 [Fully visible]. This animation should start only after the circular reveal animation is complete. So add a listener to the animation object, and override the method onAnimationEnd(Animator animator) to know when the animation ends.

400: Invalid request

SEE MATERIAL SHARING CARD IN ACTION

This is my first blog post, feel free to give valuable feedbacks, and ways to improve my blog. So what do you feel about Material Sharing Card? Hit me up in the comments section below. I will be also doing a follow up post for this.

The entire code is available on GitHub. If you have a better way to implement the same, make changes and submit pull request.

Dribbble design by Benjamin Berger
Download APK
GitHub