1 page.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 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> 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 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> 44 45 <p>In most cases, you should apply this functionality in your view XML by specifying the view 46 background 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 51 the view. It will be drawn upon, and bounded by, the nearest parent of the view with a non-null 52 background.</li> 53 </ul> 54 55 <p class="note"><strong>Note:</strong> <code>selectableItemBackgroundBorderless</code> is a new 56 attribute introduced in API level 21.</p> 57 58 59 <p>Alternatively, you can define a {@link android.graphics.drawable.RippleDrawable} 60 as 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 63 the default touch feedback color, use the theme's <code>android:colorControlHighlight</code> 64 attribute.</p> 65 66 <p>For more information, see the API reference for the {@link 67 android.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 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> 76 77 <p>To reveal a previously invisible view using this effect:</p> 78 79 <pre> 80 // previously invisible view 81 View myView = findViewById(R.id.my_view); 82 83 // get the center for the clipping circle 84 int cx = myView.getWidth() / 2; 85 int cy = myView.getHeight() / 2; 86 87 // get the final radius for the clipping circle 88 float finalRadius = (float) Math.hypot(cx, cy); 89 90 // create the animator for this view (the start radius is zero) 91 Animator anim = 92 ViewAnimationUtils.createCircularReveal(myView, cx, cy, 0, finalRadius); 93 94 // make the view visible and start the animation 95 myView.setVisibility(View.VISIBLE); 96 anim.start(); 97 </pre> 98 99 <p>To hide a previously visible view using this effect:</p> 100 101 <pre> 102 // previously visible view 103 final View myView = findViewById(R.id.my_view); 104 105 // get the center for the clipping circle 106 int cx = myView.getWidth() / 2; 107 int cy = myView.getHeight() / 2; 108 109 // get the initial radius for the clipping circle 110 float initialRadius = (float) Math.hypot(cx, cy); 111 112 // create the animation (the final radius is zero) 113 Animator anim = 114 ViewAnimationUtils.createCircularReveal(myView, cx, cy, initialRadius, 0); 115 116 // make the view invisible when the animation is done 117 anim.addListener(new AnimatorListenerAdapter() { 118 @Override 119 public void onAnimationEnd(Animator animation) { 120 super.onAnimationEnd(animation); 121 myView.setVisibility(View.INVISIBLE); 122 } 123 }); 124 125 // start the animation 126 anim.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 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> 151 152 <ul> 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> 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 159 center.</li> 160 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> 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 176 as 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 189 activated 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 id="custom-trans">Specify custom transitions</h3> 198 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> 202 203 <pre> 204 <style name="BaseAppTheme" parent="android:Theme.Material"> 205 <!-- enable window content transitions --> 206 <item name="android:windowActivityTransitions">true</item> 207 208 <!-- specify enter and exit transitions --> 209 <item name="android:windowEnterTransition">@transition/explode</item> 210 <item name="android:windowExitTransition">@transition/explode</item> 211 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> 217 </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 <!-- 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/> 227 </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 232 reference 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) 239 getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS); 240 241 // set an exit transition 242 getWindow().setExitTransition(new Explode()); 243 </pre> 244 245 <p>To specify transitions in your code, call these methods with a {@link 246 android.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 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> 262 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> 266 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> 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 274 when you launch another activity as follows:</p> 275 276 <pre> 277 startActivity(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 282 when the activity starts. To disable transitions when you start another activity, provide 283 a <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 296 ActivityOptions.makeSceneTransitionAnimation()} method.</li> 297 </ol> 298 299 <pre> 300 // get the element that receives the click event 301 final View imgContainerView = findViewById(R.id.img_container); 302 303 // get the common element for the transition in this activity 304 final View androidRobotView = findViewById(R.id.image_small); 305 306 // define a click listener 307 imgContainerView.setOnClickListener(new View.OnClickListener() { 308 @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 323 element 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()} 327 method 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 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> 335 336 <pre> 337 ActivityOptions 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 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> 348 349 <p>The {@link android.view.animation.PathInterpolator} class is a new interpolator based on a 350 Bzier 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> 353 354 <pre> 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"/> 360 </pre> 361 362 <p>The system provides XML resources for the three basic curves in the material design 363 specification:</p> 364 365 <ul> 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> 369 </ul> 370 371 <p>You can pass a {@link android.view.animation.PathInterpolator} object to the {@link 372 android.animation.Animator#setInterpolator Animator.setInterpolator()} method.</p> 373 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> 377 378 <pre> 379 ObjectAnimator mAnimator; 380 mAnimator = ObjectAnimator.ofFloat(view, View.X, View.Y, path); 381 ... 382 mAnimator.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 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> 391 392 <pre> 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"> 396 <set> 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 --> 403 </set> 404 </item> 405 <item android:state_enabled="true" 406 android:state_pressed="false" 407 android:state_focused="true"> 408 <set> 409 <objectAnimator android:propertyName="translationZ" 410 android:duration="100" 411 android:valueTo="0" 412 android:valueType="floatType"/> 413 </set> 414 </item> 415 </selector> 416 </pre> 417 418 <p> 419 To attach custom view state animations to a view, define an animator using 420 the <code>selector</code> element in an XML resource file as in this example, 421 and assign it to your view with the <code>android:stateListAnimator</code> 422 attribute. To assign a state list animator to a view in your code, use the 423 {@link android.animation.AnimatorInflater#loadStateListAnimator 424 AnimatorInflater.loadStateListAnimator()} method, and assign the animator to 425 your view with the {@link android.view.View#setStateListAnimator 426 View.setStateListAnimator()} method. 427 </p> 428 429 <p>When your theme extends the material theme, buttons have a Z animation by default. To avoid this 430 behavior in your buttons, set the <code>android:stateListAnimator</code> attribute to 431 <code>@null</code>.</p> 432 433 <p>The {@link android.graphics.drawable.AnimatedStateListDrawable} class lets you create drawables 434 that show animations between state changes of the associated view. Some of the system widgets in 435 Android 5.0 use these animations by default. The following example shows how 436 to define an {@link android.graphics.drawable.AnimatedStateListDrawable} as an XML resource:</p> 437 438 <pre> 439 <!-- res/drawable/myanimstatedrawable.xml --> 440 <animated-selector 441 xmlns:android="http://schemas.android.com/apk/res/android"> 442 443 <!-- provide a different drawable for each state--> 444 <item android:id="@+id/pressed" android:drawable="@drawable/drawableP" 445 android:state_pressed="true"/> 446 <item android:id="@+id/focused" android:drawable="@drawable/drawableF" 447 android:state_focused="true"/> 448 <item android:id="@id/default" 449 android:drawable="@drawable/drawableD"/> 450 451 <!-- specify a transition --> 452 <transition android:fromId="@+id/default" android:toId="@+id/pressed"> 453 <animation-list> 454 <item android:duration="15" android:drawable="@drawable/dt1"/> 455 <item android:duration="15" android:drawable="@drawable/dt2"/> 456 ... 457 </animation-list> 458 </transition> 459 ... 460 </animated-selector> 461 </pre> 462 463 464 <h2 id="AnimVector">Animate Vector Drawables</h2> 465 466 <p><a href="{@docRoot}training/material/drawables.html#VectorDrawables">Vector Drawables</a> are 467 scalable without losing definition. The {@link android.graphics.drawable.AnimatedVectorDrawable} 468 class lets you animate the properties of a vector drawable.</p> 469 470 <p>You normally define animated vector drawables in three XML files:</p> 471 472 <ul> 473 <li>A vector drawable with the <code><vector></code> element in 474 <code>res/drawable/</code></li> 475 <li>An animated vector drawable with the <code><animated-vector></code> element in 476 <code>res/drawable/</code></li> 477 <li>One or more object animators with the <code><objectAnimator></code> element in 478 <code>res/anim/</code></li> 479 </ul> 480 481 <p>Animated vector drawables can animate the attributes of the <code><group></code> and 482 <code><path></code> elements. The <code><group></code> elements defines a set of 483 paths or subgroups, and the <code><path></code> element defines paths to be drawn.</p> 484 485 <p>When you define a vector drawable that you want to animate, use the <code>android:name</code> 486 attribute to assign a unique name to groups and paths, so you can refer to them from your animator 487 definitions. For example:</p> 488 489 <pre> 490 <!-- res/drawable/vectordrawable.xml --> 491 <vector xmlns:android="http://schemas.android.com/apk/res/android" 492 android:height="64dp" 493 android:width="64dp" 494 android:viewportHeight="600" 495 android:viewportWidth="600"> 496 <group 497 <strong>android:name="rotationGroup"</strong> 498 android:pivotX="300.0" 499 android:pivotY="300.0" 500 android:rotation="45.0" > 501 <path 502 <strong>android:name="v"</strong> 503 android:fillColor="#000000" 504 android:pathData="M300,70 l 0,-70 70,70 0,0 -70,70z" /> 505 </group> 506 </vector> 507 </pre> 508 509 <p>The animated vector drawable definition refers to the groups and paths in the vector drawable 510 by their names:</p> 511 512 <pre> 513 <!-- res/drawable/animvectordrawable.xml --> 514 <animated-vector xmlns:android="http://schemas.android.com/apk/res/android" 515 android:drawable="@drawable/vectordrawable" > 516 <target 517 android:name="rotationGroup" 518 android:animation="@anim/rotation" /> 519 <target 520 android:name="v" 521 android:animation="@anim/path_morph" /> 522 </animated-vector> 523 </pre> 524 525 <p>The animation definitions represent {@link android.animation.ObjectAnimator} or {@link 526 android.animation.AnimatorSet} objects. The first animator in this example rotates the target 527 group 360 degrees:</p> 528 529 <pre> 530 <!-- res/anim/rotation.xml --> 531 <objectAnimator 532 android:duration="6000" 533 android:propertyName="rotation" 534 android:valueFrom="0" 535 android:valueTo="360" /> 536 </pre> 537 538 <p>The second animator in this example morphs the vector drawable's path from one shape to 539 another. Both paths must be compatible for morphing: they must have the same number of commands 540 and the same number of parameters for each command.</p> 541 542 <pre> 543 <!-- res/anim/path_morph.xml --> 544 <set xmlns:android="http://schemas.android.com/apk/res/android"> 545 <objectAnimator 546 android:duration="3000" 547 android:propertyName="pathData" 548 android:valueFrom="M300,70 l 0,-70 70,70 0,0 -70,70z" 549 android:valueTo="M300,70 l 0,-70 70,0 0,140 -70,0 z" 550 android:valueType="pathType" /> 551 </set> 552 </pre> 553 554 <p>For more information, see the API reference for {@link 555 android.graphics.drawable.AnimatedVectorDrawable}.</p> 556