1page.title=Defining Custom Animations
2
3@jd:body
4
5<div id="tb-wrapper">
6<div id="tb">
7<h2>This lesson teaches you to</h2>
8<ol>
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>
14</ol>
15<h2>You should also read</h2>
16<ul>
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>
19</ul>
20</div>
21</div>
22
23
24<p>Animations in material design give users feedback on their actions and provide visual
25continuity as users interact with your app. The material theme provides some default animations
26for buttons and activity transitions, and Android 5.0 (API level 21) and above lets you customize
27these animations and create new ones:</p>
28
29<ul>
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>
35</ul>
36
37
38<h2 id="Touch">Customize Touch Feedback</h2>
39
40<p>Touch feedback in material design provides an instantaneous visual confirmation at the
41point of contact when users interact with UI elements. The default touch feedback animations
42for buttons use the new {@link android.graphics.drawable.RippleDrawable} class, which transitions
43between different states with a ripple effect.</p>
44
45<p>In most cases, you should apply this functionality in your view XML by specifying the view
46background as:</p>
47
48<ul>
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
51the view. It will be drawn upon, and bounded by, the nearest parent of the view with a non-null
52background.</li>
53</ul>
54
55<p class="note"><strong>Note:</strong> <code>selectableItemBackgroundBorderless</code> is a new
56attribute introduced in API level 21.</p>
57
58
59<p>Alternatively, you can define a {@link android.graphics.drawable.RippleDrawable}
60as an XML resource using the <code>ripple</code> element.</p>
61
62<p>You can assign a color to {@link android.graphics.drawable.RippleDrawable} objects. To change
63the default touch feedback color, use the theme's <code>android:colorControlHighlight</code>
64attribute.</p>
65
66<p>For more information, see the API reference for the {@link
67android.graphics.drawable.RippleDrawable} class.</p>
68
69
70<h2 id="Reveal">Use the Reveal Effect</h2>
71
72<p>Reveal animations provide users visual continuity when you show or hide a group of UI
73elements. The {@link android.view.ViewAnimationUtils#createCircularReveal
74ViewAnimationUtils.createCircularReveal()} method enables you to animate a clipping circle to
75reveal or hide a view.</p>
76
77<p>To reveal a previously invisible view using this effect:</p>
78
79<pre>
80// previously invisible view
81View myView = findViewById(R.id.my_view);
82
83// get the center for the clipping circle
84int cx = myView.getWidth() / 2;
85int cy = myView.getHeight() / 2;
86
87// get the final radius for the clipping circle
88int finalRadius = Math.max(myView.getWidth(), myView.getHeight());
89
90// create the animator for this view (the start radius is zero)
91Animator anim =
92    ViewAnimationUtils.createCircularReveal(myView, cx, cy, 0, finalRadius);
93
94// make the view visible and start the animation
95myView.setVisibility(View.VISIBLE);
96anim.start();
97</pre>
98
99<p>To hide a previously visible view using this effect:</p>
100
101<pre>
102// previously visible view
103final View myView = findViewById(R.id.my_view);
104
105// get the center for the clipping circle
106int cx = myView.getWidth() / 2;
107int cy = myView.getHeight() / 2;
108
109// get the initial radius for the clipping circle
110int initialRadius = myView.getWidth();
111
112// create the animation (the final radius is zero)
113Animator anim =
114    ViewAnimationUtils.createCircularReveal(myView, cx, cy, initialRadius, 0);
115
116// make the view invisible when the animation is done
117anim.addListener(new AnimatorListenerAdapter() {
118    &#64;Override
119    public void onAnimationEnd(Animator animation) {
120        super.onAnimationEnd(animation);
121        myView.setVisibility(View.INVISIBLE);
122    }
123});
124
125// start the animation
126anim.start();
127</pre>
128
129
130<h2 id="Transitions">Customize Activity Transitions</h2>
131
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">
139  </video>
140  </div>
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>
145  </div>
146</div>
147
148<p>Activity transitions in material design apps provide visual connections between different states
149through motion and transformations between common elements. You can specify custom animations for
150enter and exit transitions and for transitions of shared elements between activities.</p>
151
152<ul>
153<li>An <strong>enter</strong> transition determines how views in an activity enter the scene.
154For example, in the <em>explode</em> enter transition, the views enter the scene from the outside
155and fly in towards the center of the screen.</li>
156
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
159center.</li>
160
161<li>A <strong>shared elements</strong> transition determines how views that are shared between
162two activities transition between these activities. For example, if two activities have the same
163image in different positions and sizes, the <em>changeImageTransform</em> shared element transition
164translates and scales the image smoothly between these activities.</li>
165</ul>
166
167<p>Android 5.0 (API level 21) supports these enter and exit transitions:</p>
168
169<ul>
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>
173</ul>
174
175<p>Any transition that extends the {@link android.transition.Visibility} class is supported
176as an enter or exit transition. For more information, see the API reference for the
177{@link android.transition.Transition} class.</p>
178
179<p>Android 5.0 (API level 21) also supports these shared elements transitions:</p>
180
181<ul>
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>
186</ul>
187
188<p>When you enable activity transitions in your app, the default cross-fading transition is
189activated between the entering and exiting activities.</p>
190
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.
195</p>
196
197<h3>Specify custom transitions</h3>
198
199<p>First, enable window content transitions with the <code>android:windowContentTransitions</code>
200attribute when you define a style that inherits from the material theme. You can also specify
201enter, exit, and shared element transitions in your style definition:</p>
202
203<pre>
204&lt;style name="BaseAppTheme" parent="android:Theme.Material">
205  &lt;!-- enable window content transitions -->
206  &lt;item name="android:windowContentTransitions">true&lt;/item>
207
208  &lt;!-- specify enter and exit transitions -->
209  &lt;item name="android:windowEnterTransition">@transition/explode&lt;/item>
210  &lt;item name="android:windowExitTransition">@transition/explode&lt;/item>
211
212  &lt;!-- specify shared element transitions -->
213  &lt;item name="android:windowSharedElementEnterTransition">
214    &#64;transition/change_image_transform&lt;/item>
215  &lt;item name="android:windowSharedElementExitTransition">
216    &#64;transition/change_image_transform&lt;/item>
217&lt;/style>
218</pre>
219
220<p>The <code>change_image_transform</code> transition in this example is defined as follows:</p>
221
222<pre>
223&lt;!-- res/transition/change_image_transform.xml -->
224&lt;!-- (see also Shared Transitions below) -->
225&lt;transitionSet xmlns:android="http://schemas.android.com/apk/res/android">
226  &lt;changeImageTransform/>
227&lt;/transitionSet>
228</pre>
229
230<p>The <code>changeImageTransform</code> element corresponds to the
231{@link android.transition.ChangeImageTransform} class. For more information, see the API
232reference for {@link android.transition.Transition}.</p>
233
234<p>To enable window content transitions in your code instead, call the
235{@link android.view.Window#requestFeature Window.requestFeature()} method:</p>
236
237<pre>
238// inside your activity (if you did not enable transitions in your theme)
239getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);
240
241// set an exit transition
242getWindow().setExitTransition(new Explode());
243</pre>
244
245<p>To specify transitions in your code, call these methods with a {@link
246android.transition.Transition} object:</p>
247
248<ul>
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>
255</ul>
256
257<p>The {@link android.view.Window#setExitTransition setExitTransition()} and {@link
258android.view.Window#setSharedElementExitTransition setSharedElementExitTransition()} methods define
259the exit transition for the calling activity. The {@link android.view.Window#setEnterTransition
260setEnterTransition()} and {@link android.view.Window#setSharedElementEnterTransition
261setSharedElementEnterTransition()} methods define the enter transition for the called activity.</p>
262
263<p>To get the full effect of a transition, you must enable window content transitions on both the
264calling and called activities. Otherwise, the calling activity will start the exit transition,
265but then you'll see a window transition (like scale or fade).</p>
266
267<p>To start an enter transition as soon as possible, use the
268{@link android.view.Window#setAllowEnterTransitionOverlap Window.setAllowEnterTransitionOverlap()}
269method on the called activity. This lets you have more dramatic enter transitions.</p>
270
271<h3>Start an activity using transitions</h3>
272
273<p>If you enable transitions and set an exit transition for an activity, the transition is activated
274when you launch another activity as follows:</p>
275
276<pre>
277startActivity(intent,
278              ActivityOptions.makeSceneTransitionAnimation(this).toBundle());
279</pre>
280
281<p>If you have set an enter transition for the second activity, the transition is also activated
282when the activity starts. To disable transitions when you start another activity, provide
283a <code>null</code> options bundle.</p>
284
285<h3>Start an activity with a shared element</h3>
286
287<p>To make a screen transition animation between two activities that have a shared element:</p>
288
289<ol>
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
296ActivityOptions.makeSceneTransitionAnimation()} method.</li>
297</ol>
298
299<pre>
300// get the element that receives the click event
301final View imgContainerView = findViewById(R.id.img_container);
302
303// get the common element for the transition in this activity
304final View androidRobotView = findViewById(R.id.image_small);
305
306// define a click listener
307imgContainerView.setOnClickListener(new View.OnClickListener() {
308    &#64;Override
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());
317    }
318});
319</pre>
320
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
323element name in both activities.</p>
324
325<p>To reverse the scene transition animation when you finish the second activity, call the
326{@link android.app.Activity#finishAfterTransition Activity.finishAfterTransition()}
327method instead of {@link android.app.Activity#finish Activity.finish()}.</p>
328
329<h3>Start an activity with multiple shared elements</h3>
330
331<p>To make a scene transition animation between two activities that have more than one shared
332element, define the shared elements in both layouts with the <code>android:transitionName</code>
333attribute (or use the {@link android.view.View#setTransitionName View.setTransitionName()} method
334in both activities), and create an {@link android.app.ActivityOptions} object as follows:</p>
335
336<pre>
337ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(this,
338        Pair.create(view1, "agreedName1"),
339        Pair.create(view2, "agreedName2"));
340</pre>
341
342
343<h2 id="CurvedMotion">Use Curved Motion</h2>
344
345<p>Animations in material design rely on curves for time interpolation and spatial movement
346patterns. With Android 5.0 (API level 21) and above, you can define custom timing curves and
347curved motion patterns for animations.</p>
348
349<p>The {@link android.view.animation.PathInterpolator} class is a new interpolator based on a
350Bézier curve or a {@link android.graphics.Path} object. This interpolator specifies a motion curve
351in a 1x1 square, with anchor points at (0,0) and (1,1) and control points as specified using the
352constructor arguments. You can also define a path interpolator as an XML resource:</p>
353
354<pre>
355&lt;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"/>
360</pre>
361
362<p>The system provides XML resources for the three basic curves in the material design
363specification:</p>
364
365<ul>
366  <li><code>&#64;interpolator/fast_out_linear_in.xml</code></li>
367  <li><code>&#64;interpolator/fast_out_slow_in.xml</code></li>
368  <li><code>&#64;interpolator/linear_out_slow_in.xml</code></li>
369</ul>
370
371<p>You can pass a {@link android.view.animation.PathInterpolator} object to the {@link
372android.animation.Animator#setInterpolator Animator.setInterpolator()} method.</p>
373
374<p>The {@link android.animation.ObjectAnimator} class has new constructors that enable you to animate
375coordinates along a path using two or more properties at once. For example, the following animator
376uses a {@link android.graphics.Path} object to animate the X and Y properties of a view:</p>
377
378<pre>
379ObjectAnimator mAnimator;
380mAnimator = ObjectAnimator.ofFloat(view, View.X, View.Y, path);
381...
382mAnimator.start();
383</pre>
384
385
386<h2 id="ViewState">Animate View State Changes</h2>
387
388<p>The {@link android.animation.StateListAnimator} class lets you define animators that run when
389the state of a view changes. The following example shows how to define an {@link
390android.animation.StateListAnimator}  as an XML resource:</p>
391
392<pre>
393&lt;!-- animate the translationZ property of a view when pressed -->
394&lt;selector xmlns:android="http://schemas.android.com/apk/res/android">
395  &lt;item android:state_pressed="true">
396    &lt;set>
397      &lt;objectAnimator android:propertyName="translationZ"
398        android:duration="@android:integer/config_shortAnimTime"
399        android:valueTo="2dp"
400        android:valueType="floatType"/>
401        &lt;!-- you could have other objectAnimator elements
402             here for "x" and "y", or other properties -->
403    &lt;/set>
404  &lt;/item>
405  &lt;item android:state_enabled="true"
406    android:state_pressed="false"
407    android:state_focused="true">
408    &lt;set>
409      &lt;objectAnimator android:propertyName="translationZ"
410        android:duration="100"
411        android:valueTo="0"
412        android:valueType="floatType"/>
413    &lt;/set>
414  &lt;/item>
415&lt;/selector>
416</pre>
417
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
420view with the <code>android:stateListAnimator</code> attribute. To assign a state list animator
421to a view in your code, use the {@link android.animation.AnimatorInflater#loadStateListAnimator
422AnimationInflater.loadStateListAnimator()} method, and assign the animator to your view with the
423{@link android.view.View#setStateListAnimator View.setStateListAnimator()} method.</p>
424
425<p>When your theme extends the material theme, buttons have a Z animation by default. To avoid this
426behavior in your buttons, set the <code>android:stateListAnimator</code> attribute to
427<code>@null</code>.</p>
428
429<p>The {@link android.graphics.drawable.AnimatedStateListDrawable} class lets you create drawables
430that show animations between state changes of the associated view. Some of the system widgets in
431Android 5.0 use these animations by default. The following example shows how
432to define an {@link android.graphics.drawable.AnimatedStateListDrawable} as an XML resource:</p>
433
434<pre>
435&lt;!-- res/drawable/myanimstatedrawable.xml -->
436&lt;animated-selector
437    xmlns:android="http://schemas.android.com/apk/res/android">
438
439    &lt;!-- provide a different drawable for each state-->
440    &lt;item android:id="@+id/pressed" android:drawable="@drawable/drawableP"
441        android:state_pressed="true"/>
442    &lt;item android:id="@+id/focused" android:drawable="@drawable/drawableF"
443        android:state_focused="true"/>
444    &lt;item android:id="@id/default"
445        android:drawable="@drawable/drawableD"/>
446
447    &lt;!-- specify a transition -->
448    &lt;transition android:fromId="@+id/default" android:toId="@+id/pressed">
449        &lt;animation-list>
450            &lt;item android:duration="15" android:drawable="@drawable/dt1"/>
451            &lt;item android:duration="15" android:drawable="@drawable/dt2"/>
452            ...
453        &lt;/animation-list>
454    &lt;/transition>
455    ...
456&lt;/animated-selector>
457</pre>
458
459
460<h2 id="AnimVector">Animate Vector Drawables</h2>
461
462<p><a href="{@docRoot}training/material/drawables.html#VectorDrawables">Vector Drawables</a> are
463scalable without losing definition. The {@link android.graphics.drawable.AnimatedVectorDrawable}
464class lets you animate the properties of a vector drawable.</p>
465
466<p>You normally define animated vector drawables in three XML files:</p>
467
468<ul>
469<li>A vector drawable with the <code>&lt;vector&gt;</code> element in
470<code>res/drawable/</code></li>
471<li>An animated vector drawable with the <code>&lt;animated-vector&gt;</code> element in
472<code>res/drawable/</code></li>
473<li>One or more object animators with the <code>&lt;objectAnimator&gt;</code> element in
474<code>res/anim/</code></li>
475</ul>
476
477<p>Animated vector drawables can animate the attributes of the <code>&lt;group&gt;</code> and
478<code>&lt;path&gt;</code> elements. The <code>&lt;group&gt;</code> elements defines a set of
479paths or subgroups, and the <code>&lt;path&gt;</code> element defines paths to be drawn.</p>
480
481<p>When you define a vector drawable that you want to animate, use the <code>android:name</code>
482attribute to assign a unique name to groups and paths, so you can refer to them from your animator
483definitions. For example:</p>
484
485<pre>
486&lt;!-- res/drawable/vectordrawable.xml -->
487&lt;vector xmlns:android="http://schemas.android.com/apk/res/android"
488    android:height="64dp"
489    android:width="64dp"
490    android:viewportHeight="600"
491    android:viewportWidth="600">
492    &lt;group
493        <strong>android:name="rotationGroup"</strong>
494        android:pivotX="300.0"
495        android:pivotY="300.0"
496        android:rotation="45.0" >
497        &lt;path
498            <strong>android:name="v"</strong>
499            android:fillColor="#000000"
500            android:pathData="M300,70 l 0,-70 70,70 0,0 -70,70z" />
501    &lt;/group>
502&lt;/vector>
503</pre>
504
505<p>The animated vector drawable definition refers to the groups and paths in the vector drawable
506by their names:</p>
507
508<pre>
509&lt;!-- res/drawable/animvectordrawable.xml -->
510&lt;animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
511  android:drawable="@drawable/vectordrawable" >
512    &lt;target
513        android:name="rotationGroup"
514        android:animation="@anim/rotation" />
515    &lt;target
516        android:name="v"
517        android:animation="@anim/path_morph" />
518&lt;/animated-vector>
519</pre>
520
521<p>The animation definitions represent {@link android.animation.ObjectAnimator} or {@link
522android.animation.AnimatorSet} objects. The first animator in this example rotates the target
523group 360 degrees:</p>
524
525<pre>
526&lt;!-- res/anim/rotation.xml -->
527&lt;objectAnimator
528    android:duration="6000"
529    android:propertyName="rotation"
530    android:valueFrom="0"
531    android:valueTo="360" />
532</pre>
533
534<p>The second animator in this example morphs the vector drawable's path from one shape to
535another. Both paths must be compatible for morphing: they must have the same number of commands
536and the same number of parameters for each command.</p>
537
538<pre>
539&lt;!-- res/anim/path_morph.xml -->
540&lt;set xmlns:android="http://schemas.android.com/apk/res/android">
541    &lt;objectAnimator
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" />
547&lt;/set>
548</pre>
549
550<p>For more information, see the API reference for {@link
551android.graphics.drawable.AnimatedVectorDrawable}.</p>
552