1 page.title=Defining Custom Animations
7 <h2>This lesson teaches you to</h2>
9 <li><a href="#Touch">Customize Touch Feedback</a></li>
10 <li><a href="#Reveal">Use the Reveal Effect</a></li>
11 <li><a href="#Transitions">Customize Activity Transitions</a></li>
12 <li><a href="#ViewState">Animate View State Changes</a></li>
13 <li><a href="#AnimVector">Animate Vector Drawables</a></li>
15 <h2>You should also read</h2>
17 <li><a href="http://www.google.com/design/spec">Material design specification</a></li>
18 <li><a href="{@docRoot}design/material/index.html">Material design on Android</a></li>
24 <p>Animations in material design give users feedback on their actions and provide visual
25 continuity as users interact with your app. The material theme provides some default animations
26 for buttons and activity transitions, and Android 5.0 (API level 21) and above lets you customize
27 these animations and create new ones:</p>
30 <li>Touch feedback</li>
31 <li>Circular Reveal</li>
32 <li>Activity transitions</li>
33 <li>Curved motion</li>
34 <li>View state changes</li>
38 <h2 id="Touch">Customize Touch Feedback</h2>
40 <p>Touch feedback in material design provides an instantaneous visual confirmation at the
41 point of contact when users interact with UI elements. The default touch feedback animations
42 for buttons use the new {@link android.graphics.drawable.RippleDrawable} class, which transitions
43 between different states with a ripple effect.</p>
45 <p>In most cases, you should apply this functionality in your view XML by specifying the view
49 <li><code>?android:attr/selectableItemBackground</code> for a bounded ripple.</li>
50 <li><code>?android:attr/selectableItemBackgroundBorderless</code> for a ripple that extends beyond
51 the view. It will be drawn upon, and bounded by, the nearest parent of the view with a non-null
55 <p class="note"><strong>Note:</strong> <code>selectableItemBackgroundBorderless</code> is a new
56 attribute introduced in API level 21.</p>
59 <p>Alternatively, you can define a {@link android.graphics.drawable.RippleDrawable}
60 as an XML resource using the <code>ripple</code> element.</p>
62 <p>You can assign a color to {@link android.graphics.drawable.RippleDrawable} objects. To change
63 the default touch feedback color, use the theme's <code>android:colorControlHighlight</code>
66 <p>For more information, see the API reference for the {@link
67 android.graphics.drawable.RippleDrawable} class.</p>
70 <h2 id="Reveal">Use the Reveal Effect</h2>
72 <p>Reveal animations provide users visual continuity when you show or hide a group of UI
73 elements. The {@link android.view.ViewAnimationUtils#createCircularReveal
74 ViewAnimationUtils.createCircularReveal()} method enables you to animate a clipping circle to
75 reveal or hide a view.</p>
77 <p>To reveal a previously invisible view using this effect:</p>
80 // previously invisible view
81 View myView = findViewById(R.id.my_view);
83 // get the center for the clipping circle
84 int cx = myView.getWidth() / 2;
85 int cy = myView.getHeight() / 2;
87 // get the final radius for the clipping circle
88 float finalRadius = (float) Math.hypot(cx, cy);
90 // create the animator for this view (the start radius is zero)
92 ViewAnimationUtils.createCircularReveal(myView, cx, cy, 0, finalRadius);
94 // make the view visible and start the animation
95 myView.setVisibility(View.VISIBLE);
99 <p>To hide a previously visible view using this effect:</p>
102 // previously visible view
103 final View myView = findViewById(R.id.my_view);
105 // get the center for the clipping circle
106 int cx = myView.getWidth() / 2;
107 int cy = myView.getHeight() / 2;
109 // get the initial radius for the clipping circle
110 float initialRadius = (float) Math.hypot(cx, cy);
112 // create the animation (the final radius is zero)
114 ViewAnimationUtils.createCircularReveal(myView, cx, cy, initialRadius, 0);
116 // make the view invisible when the animation is done
117 anim.addListener(new AnimatorListenerAdapter() {
119 public void onAnimationEnd(Animator animation) {
120 super.onAnimationEnd(animation);
121 myView.setVisibility(View.INVISIBLE);
125 // start the animation
130 <h2 id="Transitions">Customize Activity Transitions</h2>
132 <!-- shared transition video -->
133 <div style="width:290px;margin-left:35px;float:right">
134 <div class="framed-nexus5-port-span-5">
135 <video class="play-on-hover" autoplay="">
136 <source src="{@docRoot}design/material/videos/ContactsAnim.mp4">
137 <source src="{@docRoot}design/material/videos/ContactsAnim.webm">
138 <source src="{@docRoot}design/material/videos/ContactsAnim.ogv">
141 <div style="font-size:10pt;margin-left:20px;margin-bottom:30px">
142 <p class="img-caption" style="margin-top:3px;margin-bottom:10px"><strong>Figure 1</strong> - A
143 transition with shared elements.</p>
144 <em>To replay the movie, click on the device screen</em>
148 <p>Activity transitions in material design apps provide visual connections between different states
149 through motion and transformations between common elements. You can specify custom animations for
150 enter and exit transitions and for transitions of shared elements between activities.</p>
153 <li>An <strong>enter</strong> transition determines how views in an activity enter the scene.
154 For example, in the <em>explode</em> enter transition, the views enter the scene from the outside
155 and fly in towards the center of the screen.</li>
157 <li>An <strong>exit</strong> transition determines how views in an activity exit the scene. For
158 example, in the <em>explode</em> exit transition, the views exit the scene away from the
161 <li>A <strong>shared elements</strong> transition determines how views that are shared between
162 two activities transition between these activities. For example, if two activities have the same
163 image in different positions and sizes, the <em>changeImageTransform</em> shared element transition
164 translates and scales the image smoothly between these activities.</li>
167 <p>Android 5.0 (API level 21) supports these enter and exit transitions:</p>
170 <li><em>explode</em> - Moves views in or out from the center of the scene.</li>
171 <li><em>slide</em> - Moves views in or out from one of the edges of the scene.</li>
172 <li><em>fade</em> - Adds or removes a view from the scene by changing its opacity.</li>
175 <p>Any transition that extends the {@link android.transition.Visibility} class is supported
176 as an enter or exit transition. For more information, see the API reference for the
177 {@link android.transition.Transition} class.</p>
179 <p>Android 5.0 (API level 21) also supports these shared elements transitions:</p>
182 <li><em>changeBounds</em> - Animates the changes in layout bounds of target views.</li>
183 <li><em>changeClipBounds</em> - Animates the changes in clip bounds of target views.</li>
184 <li><em>changeTransform</em> - Animates the changes in scale and rotation of target views.</li>
185 <li><em>changeImageTransform</em> - Animates changes in size and scale of target images.</li>
188 <p>When you enable activity transitions in your app, the default cross-fading transition is
189 activated between the entering and exiting activities.</p>
191 <img src="{@docRoot}training/material/images/SceneTransition.png" alt="" width="600" height="405"
192 style="margin-top:20px"/>
193 <p class="img-caption">
194 Â <strong>Figure 2</strong> - A scene transition with one shared element.
197 <h3 id="custom-trans">Specify custom transitions</h3>
199 <p>First, enable window content transitions with the <code>android:windowActivityTransitions</code>
200 attribute when you define a style that inherits from the material theme. You can also specify
201 enter, exit, and shared element transitions in your style definition:</p>
204 <style name="BaseAppTheme" parent="android:Theme.Material">
205 <!-- enable window content transitions -->
206 <item name="android:android:windowActivityTransitions">true</item>
208 <!-- specify enter and exit transitions -->
209 <item name="android:windowEnterTransition">@transition/explode</item>
210 <item name="android:windowExitTransition">@transition/explode</item>
212 <!-- specify shared element transitions -->
213 <item name="android:windowSharedElementEnterTransition">
214 @transition/change_image_transform</item>
215 <item name="android:windowSharedElementExitTransition">
216 @transition/change_image_transform</item>
220 <p>The <code>change_image_transform</code> transition in this example is defined as follows:</p>
223 <!-- res/transition/change_image_transform.xml -->
224 <!-- (see also Shared Transitions below) -->
225 <transitionSet xmlns:android="http://schemas.android.com/apk/res/android">
226 <changeImageTransform/>
230 <p>The <code>changeImageTransform</code> element corresponds to the
231 {@link android.transition.ChangeImageTransform} class. For more information, see the API
232 reference for {@link android.transition.Transition}.</p>
234 <p>To enable window content transitions in your code instead, call the
235 {@link android.view.Window#requestFeature Window.requestFeature()} method:</p>
238 // inside your activity (if you did not enable transitions in your theme)
239 getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);
241 // set an exit transition
242 getWindow().setExitTransition(new Explode());
245 <p>To specify transitions in your code, call these methods with a {@link
246 android.transition.Transition} object:</p>
249 <li>{@link android.view.Window#setEnterTransition Window.setEnterTransition()}</li>
250 <li>{@link android.view.Window#setExitTransition Window.setExitTransition()}</li>
251 <li>{@link android.view.Window#setSharedElementEnterTransition
252 Window.setSharedElementEnterTransition()}</li>
253 <li>{@link android.view.Window#setSharedElementExitTransition
254 Window.setSharedElementExitTransition()}</li>
257 <p>The {@link android.view.Window#setExitTransition setExitTransition()} and {@link
258 android.view.Window#setSharedElementExitTransition setSharedElementExitTransition()} methods define
259 the exit transition for the calling activity. The {@link android.view.Window#setEnterTransition
260 setEnterTransition()} and {@link android.view.Window#setSharedElementEnterTransition
261 setSharedElementEnterTransition()} methods define the enter transition for the called activity.</p>
263 <p>To get the full effect of a transition, you must enable window content transitions on both the
264 calling and called activities. Otherwise, the calling activity will start the exit transition,
265 but then you'll see a window transition (like scale or fade).</p>
267 <p>To start an enter transition as soon as possible, use the
268 {@link android.view.Window#setAllowEnterTransitionOverlap Window.setAllowEnterTransitionOverlap()}
269 method on the called activity. This lets you have more dramatic enter transitions.</p>
271 <h3>Start an activity using transitions</h3>
273 <p>If you enable transitions and set an exit transition for an activity, the transition is activated
274 when you launch another activity as follows:</p>
277 startActivity(intent,
278 ActivityOptions.makeSceneTransitionAnimation(this).toBundle());
281 <p>If you have set an enter transition for the second activity, the transition is also activated
282 when the activity starts. To disable transitions when you start another activity, provide
283 a <code>null</code> options bundle.</p>
285 <h3>Start an activity with a shared element</h3>
287 <p>To make a screen transition animation between two activities that have a shared element:</p>
290 <li>Enable window content transitions in your theme.</li>
291 <li>Specify a shared elements transition in your style.</li>
292 <li>Define your transition as an XML resource.</li>
293 <li>Assign a common name to the shared elements in both layouts with the
294 <code>android:transitionName</code> attribute.</li>
295 <li>Use the {@link android.app.ActivityOptions#makeSceneTransitionAnimation
296 ActivityOptions.makeSceneTransitionAnimation()} method.</li>
300 // get the element that receives the click event
301 final View imgContainerView = findViewById(R.id.img_container);
303 // get the common element for the transition in this activity
304 final View androidRobotView = findViewById(R.id.image_small);
306 // define a click listener
307 imgContainerView.setOnClickListener(new View.OnClickListener() {
309 public void onClick(View view) {
310 Intent intent = new Intent(this, Activity2.class);
311 // create the transition animation - the images in the layouts
312 // of both activities are defined with android:transitionName="robot"
313 ActivityOptions options = ActivityOptions
314 .makeSceneTransitionAnimation(this, androidRobotView, "robot");
315 // start the new activity
316 startActivity(intent, options.toBundle());
321 <p>For shared dynamic views that you generate in your code, use the
322 {@link android.view.View#setTransitionName View.setTransitionName()} method to specify a common
323 element name in both activities.</p>
325 <p>To reverse the scene transition animation when you finish the second activity, call the
326 {@link android.app.Activity#finishAfterTransition Activity.finishAfterTransition()}
327 method instead of {@link android.app.Activity#finish Activity.finish()}.</p>
329 <h3>Start an activity with multiple shared elements</h3>
331 <p>To make a scene transition animation between two activities that have more than one shared
332 element, define the shared elements in both layouts with the <code>android:transitionName</code>
333 attribute (or use the {@link android.view.View#setTransitionName View.setTransitionName()} method
334 in both activities), and create an {@link android.app.ActivityOptions} object as follows:</p>
337 ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(this,
338 Pair.create(view1, "agreedName1"),
339 Pair.create(view2, "agreedName2"));
343 <h2 id="CurvedMotion">Use Curved Motion</h2>
345 <p>Animations in material design rely on curves for time interpolation and spatial movement
346 patterns. With Android 5.0 (API level 21) and above, you can define custom timing curves and
347 curved motion patterns for animations.</p>
349 <p>The {@link android.view.animation.PathInterpolator} class is a new interpolator based on a
350 Bézier curve or a {@link android.graphics.Path} object. This interpolator specifies a motion curve
351 in a 1x1 square, with anchor points at (0,0) and (1,1) and control points as specified using the
352 constructor arguments. You can also define a path interpolator as an XML resource:</p>
355 <pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
356 android:controlX1="0.4"
357 android:controlY1="0"
358 android:controlX2="1"
359 android:controlY2="1"/>
362 <p>The system provides XML resources for the three basic curves in the material design
366 <li><code>@interpolator/fast_out_linear_in.xml</code></li>
367 <li><code>@interpolator/fast_out_slow_in.xml</code></li>
368 <li><code>@interpolator/linear_out_slow_in.xml</code></li>
371 <p>You can pass a {@link android.view.animation.PathInterpolator} object to the {@link
372 android.animation.Animator#setInterpolator Animator.setInterpolator()} method.</p>
374 <p>The {@link android.animation.ObjectAnimator} class has new constructors that enable you to animate
375 coordinates along a path using two or more properties at once. For example, the following animator
376 uses a {@link android.graphics.Path} object to animate the X and Y properties of a view:</p>
379 ObjectAnimator mAnimator;
380 mAnimator = ObjectAnimator.ofFloat(view, View.X, View.Y, path);
386 <h2 id="ViewState">Animate View State Changes</h2>
388 <p>The {@link android.animation.StateListAnimator} class lets you define animators that run when
389 the state of a view changes. The following example shows how to define an {@link
390 android.animation.StateListAnimator} as an XML resource:</p>
393 <!-- animate the translationZ property of a view when pressed -->
394 <selector xmlns:android="http://schemas.android.com/apk/res/android">
395 <item android:state_pressed="true">
397 <objectAnimator android:propertyName="translationZ"
398 android:duration="@android:integer/config_shortAnimTime"
399 android:valueTo="2dp"
400 android:valueType="floatType"/>
401 <!-- you could have other objectAnimator elements
402 here for "x" and "y", or other properties -->
405 <item android:state_enabled="true"
406 android:state_pressed="false"
407 android:state_focused="true">
409 <objectAnimator android:propertyName="translationZ"
410 android:duration="100"
412 android:valueType="floatType"/>
418 <p>To attach custom view state animations to a view, define an animator using the
419 <code>selector</code> element in an XML resource file as in this example, and assign it to your
420 view with the <code>android:stateListAnimator</code> attribute. To assign a state list animator
421 to a view in your code, use the {@link android.animation.AnimatorInflater#loadStateListAnimator
422 AnimationInflater.loadStateListAnimator()} method, and assign the animator to your view with the
423 {@link android.view.View#setStateListAnimator View.setStateListAnimator()} method.</p>
425 <p>When your theme extends the material theme, buttons have a Z animation by default. To avoid this
426 behavior in your buttons, set the <code>android:stateListAnimator</code> attribute to
427 <code>@null</code>.</p>
429 <p>The {@link android.graphics.drawable.AnimatedStateListDrawable} class lets you create drawables
430 that show animations between state changes of the associated view. Some of the system widgets in
431 Android 5.0 use these animations by default. The following example shows how
432 to define an {@link android.graphics.drawable.AnimatedStateListDrawable} as an XML resource:</p>
435 <!-- res/drawable/myanimstatedrawable.xml -->
436 <animated-selector
437 xmlns:android="http://schemas.android.com/apk/res/android">
439 <!-- provide a different drawable for each state-->
440 <item android:id="@+id/pressed" android:drawable="@drawable/drawableP"
441 android:state_pressed="true"/>
442 <item android:id="@+id/focused" android:drawable="@drawable/drawableF"
443 android:state_focused="true"/>
444 <item android:id="@id/default"
445 android:drawable="@drawable/drawableD"/>
447 <!-- specify a transition -->
448 <transition android:fromId="@+id/default" android:toId="@+id/pressed">
450 <item android:duration="15" android:drawable="@drawable/dt1"/>
451 <item android:duration="15" android:drawable="@drawable/dt2"/>
456 </animated-selector>
460 <h2 id="AnimVector">Animate Vector Drawables</h2>
462 <p><a href="{@docRoot}training/material/drawables.html#VectorDrawables">Vector Drawables</a> are
463 scalable without losing definition. The {@link android.graphics.drawable.AnimatedVectorDrawable}
464 class lets you animate the properties of a vector drawable.</p>
466 <p>You normally define animated vector drawables in three XML files:</p>
469 <li>A vector drawable with the <code><vector></code> element in
470 <code>res/drawable/</code></li>
471 <li>An animated vector drawable with the <code><animated-vector></code> element in
472 <code>res/drawable/</code></li>
473 <li>One or more object animators with the <code><objectAnimator></code> element in
474 <code>res/anim/</code></li>
477 <p>Animated vector drawables can animate the attributes of the <code><group></code> and
478 <code><path></code> elements. The <code><group></code> elements defines a set of
479 paths or subgroups, and the <code><path></code> element defines paths to be drawn.</p>
481 <p>When you define a vector drawable that you want to animate, use the <code>android:name</code>
482 attribute to assign a unique name to groups and paths, so you can refer to them from your animator
483 definitions. For example:</p>
486 <!-- res/drawable/vectordrawable.xml -->
487 <vector xmlns:android="http://schemas.android.com/apk/res/android"
488 android:height="64dp"
490 android:viewportHeight="600"
491 android:viewportWidth="600">
493 <strong>android:name="rotationGroup"</strong>
494 android:pivotX="300.0"
495 android:pivotY="300.0"
496 android:rotation="45.0" >
498 <strong>android:name="v"</strong>
499 android:fillColor="#000000"
500 android:pathData="M300,70 l 0,-70 70,70 0,0 -70,70z" />
505 <p>The animated vector drawable definition refers to the groups and paths in the vector drawable
509 <!-- res/drawable/animvectordrawable.xml -->
510 <animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
511 android:drawable="@drawable/vectordrawable" >
513 android:name="rotationGroup"
514 android:animation="@anim/rotation" />
517 android:animation="@anim/path_morph" />
518 </animated-vector>
521 <p>The animation definitions represent {@link android.animation.ObjectAnimator} or {@link
522 android.animation.AnimatorSet} objects. The first animator in this example rotates the target
523 group 360 degrees:</p>
526 <!-- res/anim/rotation.xml -->
528 android:duration="6000"
529 android:propertyName="rotation"
530 android:valueFrom="0"
531 android:valueTo="360" />
534 <p>The second animator in this example morphs the vector drawable's path from one shape to
535 another. Both paths must be compatible for morphing: they must have the same number of commands
536 and the same number of parameters for each command.</p>
539 <!-- res/anim/path_morph.xml -->
540 <set xmlns:android="http://schemas.android.com/apk/res/android">
542 android:duration="3000"
543 android:propertyName="pathData"
544 android:valueFrom="M300,70 l 0,-70 70,70 0,0 -70,70z"
545 android:valueTo="M300,70 l 0,-70 70,0 0,140 -70,0 z"
546 android:valueType="pathType" />
550 <p>For more information, see the API reference for {@link
551 android.graphics.drawable.AnimatedVectorDrawable}.</p>