page.title=Animations @jd:body
Animations in material design give users feedback on their actions and provide visual continuity as users interact with your app. The material theme provides some default animations for buttons and activity transitions, and the Android L Developer Preview provides additional APIs that let you customize these animations and create new ones:
In the Android L Developer Preview the default touch feedback animations for buttons use the new
RippleDrawable
class, which transitions between different states with a ripple
effect.
To use this functionality in your custom views, create a RippleDrawable
and set
it as the background of your view. You can define a RippleDrawable
as an XML resource
using the ripple
element.
The View.createRevealAnimator
method enables you to animate a clipping circle
to reveal or hide a view.
To reveal a previously invisible view using this effect:
// 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 = myView.createRevealAnimator(cx, cy, 0, finalRadius); anim.start();
To hide a previously visible view using this effect:
// previously visible view final 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 initial radius for the clipping circle int initialRadius = myView.getWidth(); // create the animation (the final radius is zero) ValueAnimator anim = myView.createRevealAnimator(cx, cy, initialRadius, 0); // make the view invisible when the animation is done anim.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { super.onAnimationEnd(animation); myView.setVisibility(View.INVISIBLE); } }); // start the animation anim.start();
The Android L Developer Preview enables your app to customize the default animations for activity transitions. You can specify custom animations for enter and exit transitions and for transitions of shared elements between activities.
Figure 1 - A scene transition with one shared element.
First, enable window content transitions with the android:windowContentTransitions
attribute when you define a style that inherits from the material theme:
<style name="BaseAppTheme" parent="android:Theme.Material"> <!-- enable window content transitions --> <item name="android:windowContentTransitions">true</item> <!-- specify enter and exit transitions --> <item name="android:windowEnterTransition">@transition/explode</item> <item name="android:windowExitTransition">@transition/explode</item> <!-- specify shared element transitions --> <item name="android:windowSharedElementEnterTransition"> @transition/move_image</item> <item name="android:windowSharedElementExitTransition"> @transition/move_image</item> </style>
You can also specify enter, exit, and shared element transitions in your style definition.
The move_image
transition in this example is defined as follows:
<!-- res/transition/move_image.xml --> <!-- (see also Shared Transitions below) --> <transitionSet xmlns:android="http://schemas.android.com/apk/res/android"> <moveImage> <targets> <!-- shared view in the first activity --> <target android:targetId="@id/image_small" /> <!-- shared view in the second activity --> <target android:targetId="@id/image_big" /> </targets> </moveImage> </transitionSet>
The moveImage
element corresponds to the android.transition.MoveImage
class. For more information, see the API reference for android.transition.Transition
.
To enable window content transitions in your code instead, call the
Window.requestFeature
method:
// inside your activity getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS); // set an exit transition getWindow().setExitTransition(new Explode());
To specify transitions in your code, call these methods with a Transition
object:
Window.setEnterTransition
Window.setExitTransition
Window.setSharedElementEnterTransition
Window.setSharedElementExitTransition
If you enable transitions and set an exit transition for an activity, the transition is activated
when you launch another activity with the startActivity
method. If you have set an
enter transition for the second activity, the transition is also activated when the activity
starts.
To make a screne transition animation between two activities that have a shared element:
android:viewName
attribute.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.android_robot_img); // 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()); } });
For shared dynamic views that you generate in your code, use the View.setViewName
method to specify a common element name in both activities.
To make a scene transition animation between two activities that have more than one shared
element, define the shared elements in both layouts with the android:viewName
attribute (or use the View.setViewName
in both activities), and create an
ActivityOptions
object as follows:
ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(this, new Pair[] { Pair.create(view1, "agreedName1"), Pair.create(view2, "agreedName2"), ... } );
Animations in material design rely on curves for time interpolation and spatial movement patterns. The Android L Developer Preview provides new APIs that enable you to define custom timing curves and curved motion patterns for animations.
The PathInterpolator
class is a new interpolator based on a Bézier curve or a
Path
object. This interpolator specifies a motion curve in a 1x1 square, with anchor
points at (0,0) and (1,1) and control points as specified using the constructor arguments. You can
also define a PathInterpolator
as an XML resource:
<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android" android:controlX1="0.4" android:controlY1="0" android:controlX2="1" android:controlY2="1"/>
The Android L Developer Preview provides XML resources for the three basic curves in the material design specification:
@interpolator/fast_out_linear_in.xml
@interpolator/fast_out_slow_in.xml
@interpolator/linear_out_slow_in.xml
You can pass a PathInterpolator
object to the
Animation.setInterpolation
method.
The ObjectAnimator
class has new constructors that enable you to animate
coordinates along a path using two or more properties at once. For example, the following animator
uses a Path
object to animate the X and Y properties of a view:
ObjectAnimator mAnimator; mAnimator = ObjectAnimator.ofFloat(view, View.X, View.Y, path); ... mAnimator.start();
The new StateListAnimator
class lets you define animators that run when the state
of a view changes. The following example shows how to define an StateListAnimator
as
an XML resource:
<!-- animate the elevation property of a view when pressed --> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_pressed="true"> <set> <objectAnimator android:propertyName="elevation" android:duration="100" android:valueTo="60" android:valueType="floatType"/> <!-- you could have other objectAnimator elements here for "x" and "y", or other properties --> </set> </item> <item android:state_enabled="true" android:state_pressed="false" android:state_focused="true"> <set> <objectAnimator android:propertyName="elevation" android:duration="100" android:valueTo="10" android:valueType="floatType"/> </set> </item> </selector>
The new AnimatedStateListDrawable
class lets you create drawables that show
animations between state changes of the associated view. Some of the system widgets in the
Android L Developer Preview use these animations by default. The following example shows how
to define an AnimatedStateListDrawable
as an XML resource:
<!-- res/drawable/myanimstatedrawable.xml --> <animated-selector xmlns:android="http://schemas.android.com/apk/res/android"> <!-- provide a different drawable for each state--> <item android:id="@+id/pressed" android:drawable="@drawable/drawableP" android:state-pressed="true"/> <item android:id="@+id/focused" android:drawable="@drawable/drawableF" android:state-focused="true"/> <item android:id="@id/default" android:drawable="@drawable/drawableD"/> <!-- specify a transition --> <transition android:fromId="@+id/default" android:toId="@+id/pressed"> <animation-list> <item android:duration="15" android:drawable="@drawable/dt1"/> <item android:duration="15" android:drawable="@drawable/dt2"/> ... </animation-list> </transition> ... </animated-selector>
The Android L Developer Preview enables you to define bitmaps as an alpha mask and to tint them using a color resource or a theme attribute that resolves to a color resource. You can create these assets only once and color them automatically to match your theme.
To apply a tint to a bitmap in your code, use the setTint
method in these
classes:
PaintDrawable
NinePatchDrawable
RippleDrawable
In your layouts, use the android:tint
attribute instead.
The setTint
method also lets you set the tint blending mode for
NinePatchDrawable
and RippleDrawable
objects in your code. To set the
tint mode in your layouts, use the android:tintMode
attribute.