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 @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<style name="BaseAppTheme" parent="android:Theme.Material"> 202 <!-- enable window content transitions --> 203 <item name="android:windowContentTransitions">true</item> 204 205 <!-- specify enter and exit transitions --> 206 <item name="android:windowEnterTransition">@transition/explode</item> 207 <item name="android:windowExitTransition">@transition/explode</item> 208 209 <!-- specify shared element transitions --> 210 <item name="android:windowSharedElementEnterTransition"> 211 @transition/change_image_transform</item> 212 <item name="android:windowSharedElementExitTransition"> 213 @transition/change_image_transform</item> 214</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<!-- res/transition/change_image_transform.xml --> 221<!-- (see also Shared Transitions below) --> 222<transitionSet xmlns:android="http://schemas.android.com/apk/res/android"> 223 <changeImageTransform/> 224</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 @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<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>@interpolator/fast_out_linear_in.xml</code></li> 364 <li><code>@interpolator/fast_out_slow_in.xml</code></li> 365 <li><code>@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<!-- animate the translationZ property of a view when pressed --> 391<selector xmlns:android="http://schemas.android.com/apk/res/android"> 392 <item android:state_pressed="true"> 393 <set> 394 <objectAnimator android:propertyName="translationZ" 395 android:duration="@android:integer/config_shortAnimTime" 396 android:valueTo="2dp" 397 android:valueType="floatType"/> 398 <!-- you could have other objectAnimator elements 399 here for "x" and "y", or other properties --> 400 </set> 401 </item> 402 <item android:state_enabled="true" 403 android:state_pressed="false" 404 android:state_focused="true"> 405 <set> 406 <objectAnimator android:propertyName="translationZ" 407 android:duration="100" 408 android:valueTo="0" 409 android:valueType="floatType"/> 410 </set> 411 </item> 412</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<!-- res/drawable/myanimstatedrawable.xml --> 433<animated-selector 434 xmlns:android="http://schemas.android.com/apk/res/android"> 435 436 <!-- provide a different drawable for each state--> 437 <item android:id="@+id/pressed" android:drawable="@drawable/drawableP" 438 android:state_pressed="true"/> 439 <item android:id="@+id/focused" android:drawable="@drawable/drawableF" 440 android:state_focused="true"/> 441 <item android:id="@id/default" 442 android:drawable="@drawable/drawableD"/> 443 444 <!-- specify a transition --> 445 <transition android:fromId="@+id/default" android:toId="@+id/pressed"> 446 <animation-list> 447 <item android:duration="15" android:drawable="@drawable/dt1"/> 448 <item android:duration="15" android:drawable="@drawable/dt2"/> 449 ... 450 </animation-list> 451 </transition> 452 ... 453</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><vector></code> element in 467<code>res/drawable/</code></li> 468<li>An animated vector drawable with the <code><animated-vector></code> element in 469<code>res/drawable/</code></li> 470<li>One or more object animators with the <code><objectAnimator></code> element in 471<code>res/anim/</code></li> 472</ul> 473 474<p>Animated vector drawables can animate the attributes of the <code><group></code> and 475<code><path></code> elements. The <code><group></code> elements defines a set of 476paths or subgroups, and the <code><path></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<!-- res/drawable/vectordrawable.xml --> 484<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 <group 490 <strong>android:name="rotationGroup"</strong> 491 android:pivotX="300.0" 492 android:pivotY="300.0" 493 android:rotation="45.0" > 494 <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 </group> 499</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<!-- res/drawable/animvectordrawable.xml --> 507<animated-vector xmlns:android="http://schemas.android.com/apk/res/android" 508 android:drawable="@drawable/vectordrawable" > 509 <target 510 android:name="rotationGroup" 511 android:animation="@anim/rotation" /> 512 <target 513 android:name="v" 514 android:animation="@anim/path_morph" /> 515</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<!-- res/anim/rotation.xml --> 524<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<!-- res/anim/path_morph.xml --> 537<set xmlns:android="http://schemas.android.com/apk/res/android"> 538 <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</set> 545</pre> 546 547<p>For more information, see the API reference for {@link 548android.graphics.drawable.AnimatedVectorDrawable}.</p> 549