Home | History | Annotate | Download | only in material
      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</li>
     52 </ul>
     53 
     54 <p class="note"><strong>Note:</strong> <code>selectableItemBackgroundBorderless</code> is a new
     55 attribute introduced in API level 21.</p>
     56 
     57 
     58 <p>Alternatively, you can define a {@link android.graphics.drawable.RippleDrawable}
     59 as 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
     62 the default touch feedback color, use the theme's <code>android:colorControlHighlight</code>
     63 attribute.</p>
     64 
     65 <p>For more information, see the API reference for the {@link
     66 android.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
     72 elements. The {@link android.view.ViewAnimationUtils#createCircularReveal
     73 ViewAnimationUtils.createCircularReveal()} method enables you to animate a clipping circle to
     74 reveal 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
     80 View myView = findViewById(R.id.my_view);
     81 
     82 // get the center for the clipping circle
     83 int cx = (myView.getLeft() + myView.getRight()) / 2;
     84 int cy = (myView.getTop() + myView.getBottom()) / 2;
     85 
     86 // get the final radius for the clipping circle
     87 int finalRadius = myView.getWidth();
     88 
     89 // create and start the animator for this view
     90 // (the start radius is zero)
     91 Animator anim =
     92     ViewAnimationUtils.createCircularReveal(myView, cx, cy, 0, finalRadius);
     93 anim.start();
     94 </pre>
     95 
     96 <p>To hide a previously visible view using this effect:</p>
     97 
     98 <pre>
     99 // previously visible view
    100 final View myView = findViewById(R.id.my_view);
    101 
    102 // get the center for the clipping circle
    103 int cx = (myView.getLeft() + myView.getRight()) / 2;
    104 int cy = (myView.getTop() + myView.getBottom()) / 2;
    105 
    106 // get the initial radius for the clipping circle
    107 int initialRadius = myView.getWidth();
    108 
    109 // create the animation (the final radius is zero)
    110 Animator anim =
    111     ViewAnimationUtils.createCircularReveal(myView, cx, cy, initialRadius, 0);
    112 
    113 // make the view invisible when the animation is done
    114 anim.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
    123 anim.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
    146 through motion and transformations between common elements. You can specify custom animations for
    147 enter 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.
    151 For example, in the <em>explode</em> enter transition, the views enter the scene from the outside
    152 and 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
    156 center.</li>
    157 
    158 <li>A <strong>shared elements</strong> transition determines how views that are shared between
    159 two activities transition between these activities. For example, if two activities have the same
    160 image in different positions and sizes, the <em>changeImageTransform</em> shared element transition
    161 translates 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
    173 as 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
    186 activated 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>
    197 attribute when you define a style that inherits from the material theme. You can also specify
    198 enter, 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
    229 reference 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)
    236 getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);
    237 
    238 // set an exit transition
    239 getWindow().setExitTransition(new Explode());
    240 </pre>
    241 
    242 <p>To specify transitions in your code, call these methods with a {@link
    243 android.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
    255 android.view.Window#setSharedElementExitTransition setSharedElementExitTransition()} methods define
    256 the exit transition for the calling activity. The {@link android.view.Window#setEnterTransition
    257 setEnterTransition()} and {@link android.view.Window#setSharedElementEnterTransition
    258 setSharedElementEnterTransition()} 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
    261 calling and called activities. Otherwise, the calling activity will start the exit transition,
    262 but 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()}
    266 method 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
    271 when you launch another activity as follows:</p>
    272 
    273 <pre>
    274 startActivity(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
    279 when the activity starts. To disable transitions when you start another activity, provide
    280 a <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
    293 ActivityOptions.makeSceneTransitionAnimation()} method.</li>
    294 </ol>
    295 
    296 <pre>
    297 // get the element that receives the click event
    298 final View imgContainerView = findViewById(R.id.img_container);
    299 
    300 // get the common element for the transition in this activity
    301 final View androidRobotView = findViewById(R.id.image_small);
    302 
    303 // define a click listener
    304 imgContainerView.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
    320 element 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()}
    324 method 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
    329 element, define the shared elements in both layouts with the <code>android:transitionName</code>
    330 attribute (or use the {@link android.view.View#setTransitionName View.setTransitionName()} method
    331 in both activities), and create an {@link android.app.ActivityOptions} object as follows:</p>
    332 
    333 <pre>
    334 ActivityOptions 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
    343 patterns. With Android 5.0 (API level 21) and above, you can define custom timing curves and
    344 curved motion patterns for animations.</p>
    345 
    346 <p>The {@link android.view.animation.PathInterpolator} class is a new interpolator based on a
    347 Bzier curve or a {@link android.graphics.Path} object. This interpolator specifies a motion curve
    348 in a 1x1 square, with anchor points at (0,0) and (1,1) and control points as specified using the
    349 constructor 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
    360 specification:</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
    369 android.animation.Animator#setInterpolator Animator.setInterpolator()} method.</p>
    370 
    371 <p>The {@link android.animation.ObjectAnimator} class has new constructors that enable you to animate
    372 coordinates along a path using two or more properties at once. For example, the following animator
    373 uses a {@link android.graphics.Path} object to animate the X and Y properties of a view:</p>
    374 
    375 <pre>
    376 ObjectAnimator mAnimator;
    377 mAnimator = ObjectAnimator.ofFloat(view, View.X, View.Y, path);
    378 ...
    379 mAnimator.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
    386 the state of a view changes. The following example shows how to define an {@link
    387 android.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
    417 view with the <code>android:stateListAnimator</code> attribute. To assign a state list animator
    418 to a view in your code, use the {@link android.animation.AnimatorInflater#loadStateListAnimator
    419 AnimationInflater.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
    423 behavior 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
    427 that show animations between state changes of the associated view. Some of the system widgets in
    428 Android 5.0 use these animations by default. The following example shows how
    429 to 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
    460 scalable without losing definition. The {@link android.graphics.drawable.AnimatedVectorDrawable}
    461 class 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
    476 paths 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>
    479 attribute to assign a unique name to groups and paths, so you can refer to them from your animator
    480 definitions. 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
    503 by 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
    519 android.animation.AnimatorSet} objects. The first animator in this example rotates the target
    520 group 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
    532 another. Both paths must be compatible for morphing: they must have the same number of commands
    533 and 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
    548 android.graphics.drawable.AnimatedVectorDrawable}.</p>
    549