Expand and contract views smoothly

android, android-5.0-lollipop, material-design, user-interface

Solution

You can use the new Animation APIs in android-L to easily create most of the effects you see in this video.

Reveal Effect You can animate a clipping circle to reveal or hide a view. This is what you see when the Play button is clicked in the video. The button expands and reveals the media player.

Code to reveal a hidden view (source)

// previously invisible view
View myView = findViewById(R.id.my_view);

// get the center for the clipping circle
int cx = (myView.getLeft() + myView.getRight()) / 2;
int cy = (myView.getTop() + myView.getBottom()) / 2;

// get the final radius for the clipping circle
int finalRadius = myView.getWidth();

// create and start the animator for this view
// (the start radius is zero)
ValueAnimator anim =
    ViewAnimationUtils.createCircularReveal(myView, cx, cy, 0, finalRadius);
anim.start();

You can find the code to hide a view if you follow the above link.

Activity Enter and Exit Transitions You can specify how views enter or exit a scene.

The currently supported transitions are explode, slide and fade. Any transition that extends the `android.transition.Visibility` is also supported.

Many examples can be seen throughout the video.

Code for an explode exit transition (source)

// inside your activity
getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);

// set an exit transition
getWindow().setExitTransition(new Explode());

Activity Shared Elements Transition You can specify how an element which is shared between two activities can transition between them.

Supported transitions are:

- changeBounds - Animates the changes in layout bounds of target views.

- changeClipBounds - Animates the changes in clip bounds of target views.

- changeTransform - Animates the changes in scale and rotation of target views.

- changeImageTransform - Animates changes in size and scale type for an image view.

To make a shared element transition you need to do the following: (source)

- Enable window content transitions in your style.

- Specify a shared elements transition in your style.

- Define your transition as an XML resource.

- Assign a common name to the shared elements in both layouts with the android:viewName attribute.

Use the `ActivityOptions.makeSceneTransitionAnimation` method.

// get the element that receives the click event
final View imgContainerView = findViewById(R.id.img_container);

// get the common element for the transition in this activity
final View androidRobotView = findViewById(R.id.image_small);

// define a click listener
imgContainerView.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        Intent intent = new Intent(this, Activity2.class);
        // create the transition animation - the images in the layouts
        // of both activities are defined with android:viewName="robot"
        ActivityOptions options = ActivityOptions
            .makeSceneTransitionAnimation(this, androidRobotView, "robot");
        // start the new activity
        startActivity(intent, options.toBundle());
    }
});

One animation I haven't figured out yet is the expand/contract animation inside the same activity, which can be seen in the calendar app.

The only thing I can say about it is that they are using elevation since we can see a shadow. I'll try to hack at it a little and see if I can recreate it.

Problem

In the Material Design video, views expand and contract really smoothly. I tried to achieve that back in the days with the old Android APIs and it was really costly and slow. Is there any new APIs in Android-L to achieve those effects? Video with the effect http://www.youtube.com/watch?v=Q8TXgCzxEnw#t=26

Original source