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