Robert Ly | 4b3e912 | 2011-09-15 15:09:17 -0700 | [diff] [blame] | 1 | page.title=Property Animation |
Scott Main | 64461bf | 2013-04-11 19:32:08 -0700 | [diff] [blame] | 2 | page.tags="valueanimator","objectanimator","layouttransition","ViewPropertyAnimator" |
Robert Ly | 4b3e912 | 2011-09-15 15:09:17 -0700 | [diff] [blame] | 3 | @jd:body |
| 4 | |
| 5 | <div id="qv-wrapper"> |
| 6 | <div id="qv"> |
| 7 | <h2>In this document</h2> |
| 8 | |
| 9 | <ol> |
| 10 | <li><a href="#how">How Property Animation Works</a></li> |
| 11 | |
| 12 | <li><a href="#value-animator">Animating with ValueAnimator</a></li> |
| 13 | |
| 14 | <li><a href="#object-animator">Animating with ObjectAnimator</a></li> |
| 15 | |
| 16 | <li><a href="#choreography">Choreographing Multiple Animations with |
| 17 | AnimatorSet</a></li> |
| 18 | |
| 19 | <li><a href="#listeners">Animation Listeners</a></li> |
| 20 | |
| 21 | <li><a href="#type-evaluator">Using a TypeEvaluator</a></li> |
| 22 | |
| 23 | <li><a href="#interpolators">Using Interpolators</a></li> |
| 24 | |
| 25 | <li><a href="#keyframes">Specifying Keyframes</a></li> |
| 26 | |
| 27 | <li><a href="#layout">Animating Layout Changes to ViewGroups</a></li> |
| 28 | |
| 29 | <li><a href="#views">Animating Views</a> |
| 30 | <ol> |
| 31 | <li><a href="#view-prop-animator">ViewPropertyAnimator</a></li> |
| 32 | </ol> |
| 33 | </li> |
| 34 | |
| 35 | <li><a href="#declaring-xml">Declaring Animations in XML</a></li> |
| 36 | </ol> |
| 37 | |
| 38 | <h2>Key classes</h2> |
| 39 | |
| 40 | <ol> |
| 41 | <li><code><a href= |
| 42 | "/reference/android/animation/ValueAnimator.html">ValueAnimator</a></code></li> |
| 43 | |
| 44 | <li><code><a href= |
| 45 | "/reference/android/animation/ObjectAnimator.html">ObjectAnimator</a></code></li> |
| 46 | |
| 47 | <li><code><a href= |
| 48 | "/reference/android/animation/TypeEvaluator.html">TypeEvaluator</a></code></li> |
| 49 | </ol> |
| 50 | |
| 51 | <h2>Related samples</h2> |
| 52 | |
| 53 | <ol> |
| 54 | <li><a href= |
| 55 | "{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/animation/index.html">API |
| 56 | Demos</a></li> |
| 57 | </ol> |
| 58 | </div> |
| 59 | </div> |
| 60 | <p>The property animation system is a robust framework that allows you |
| 61 | to animate almost anything. You can define an animation to change any object property over time, |
| 62 | regardless of whether it draws to the screen or not. A property animation changes a property's |
| 63 | (a field in an object) value over a specified length of time. To animate something, you specify the |
| 64 | object property that you want to animate, such as an object's position on the screen, how long |
| 65 | you want to animate it for, and what values you want to animate between. </p> |
| 66 | |
| 67 | <p>The property animation system lets you define the following characteristics of an |
| 68 | animation:</p> |
| 69 | |
| 70 | <ul> |
| 71 | <li>Duration: You can specify the duration of an animation. The default length is 300 ms.</li> |
| 72 | |
| 73 | <li>Time interpolation: You can specify how the values for the property are calculated as a |
| 74 | function of the animation's current elapsed time.</li> |
| 75 | |
| 76 | <li>Repeat count and behavior: You can specify whether or not to have an animation repeat when |
| 77 | it reaches the end of a duration and how many times to repeat the animation. You can also |
| 78 | specify whether you want the animation to play back in reverse. Setting it to reverse plays |
| 79 | the animation forwards then backwards repeatedly, until the number of repeats is reached.</li> |
| 80 | |
| 81 | <li>Animator sets: You can group animations into logical sets that play together or |
| 82 | sequentially or after specified delays.</li> |
| 83 | |
| 84 | <li>Frame refresh delay: You can specify how often to refresh frames of your animation. The |
| 85 | default is set to refresh every 10 ms, but the speed in which your application can refresh frames is |
| 86 | ultimately dependent on how busy the system is overall and how fast the system can service the underlying timer.</li> |
| 87 | </ul> |
| 88 | |
| 89 | |
| 90 | <h2 id="how">How Property Animation Works</h2> |
| 91 | |
| 92 | <p>First, let's go over how an animation works with a simple example. Figure 1 depicts a |
| 93 | hypothetical object that is animated with its <code>x</code> property, which represents its |
| 94 | horizontal location on a screen. The duration of the animation is set to 40 ms and the distance |
| 95 | to travel is 40 pixels. Every 10 ms, which is the default frame refresh rate, the object moves |
| 96 | horizontally by 10 pixels. At the end of 40ms, the animation stops, and the object ends at |
| 97 | horizontal position 40. This is an example of an animation with linear interpolation, meaning the |
| 98 | object moves at a constant speed.</p><img src="{@docRoot}images/animation/animation-linear.png"> |
| 99 | |
| 100 | <p class="img-caption"><strong>Figure 1.</strong> Example of a linear animation</p> |
| 101 | |
| 102 | <p>You can also specify animations to have a non-linear interpolation. Figure 2 illustrates a |
| 103 | hypothetical object that accelerates at the beginning of the animation, and decelerates at the |
| 104 | end of the animation. The object still moves 40 pixels in 40 ms, but non-linearly. In the |
| 105 | beginning, this animation accelerates up to the halfway point then decelerates from the |
| 106 | halfway point until the end of the animation. As Figure 2 shows, the distance traveled |
| 107 | at the beginning and end of the animation is less than in the middle.</p><img src= |
| 108 | "{@docRoot}images/animation/animation-nonlinear.png"> |
| 109 | |
| 110 | <p class="img-caption"><strong>Figure 2.</strong> Example of a non-linear animation</p> |
| 111 | |
| 112 | <p>Let's take a detailed look at how the important components of the property animation system |
| 113 | would calculate animations like the ones illustrated above. Figure 3 depicts how the main classes |
| 114 | work with one another.</p><img src="{@docRoot}images/animation/valueanimator.png"> |
| 115 | |
| 116 | <p class="img-caption"><strong>Figure 3.</strong> How animations are calculated</p> |
| 117 | |
| 118 | <p>The {@link android.animation.ValueAnimator} object keeps track of your animation's timing, |
| 119 | such as how long the animation has been running, and the current value of the property that it is |
| 120 | animating.</p> |
| 121 | |
| 122 | <p>The {@link android.animation.ValueAnimator} encapsulates a {@link |
| 123 | android.animation.TimeInterpolator}, which defines animation interpolation, and a {@link |
| 124 | android.animation.TypeEvaluator}, which defines how to calculate values for the property being |
| 125 | animated. For example, in Figure 2, the {@link android.animation.TimeInterpolator} used would be |
| 126 | {@link android.view.animation.AccelerateDecelerateInterpolator} and the {@link |
| 127 | android.animation.TypeEvaluator} would be {@link android.animation.IntEvaluator}.</p> |
| 128 | |
| 129 | <p>To start an animation, create a {@link android.animation.ValueAnimator} and give it the |
| 130 | starting and ending values for the property that you want to animate, along with the duration of |
| 131 | the animation. When you call {@link android.animation.ValueAnimator#start start()} the animation |
| 132 | begins. During the whole animation, the {@link android.animation.ValueAnimator} calculates an <em>elapsed fraction</em> |
| 133 | between 0 and 1, based on the duration of the animation and how much time has elapsed. The |
| 134 | elapsed fraction represents the percentage of time that the animation has completed, 0 meaning 0% |
| 135 | and 1 meaning 100%. For example, in Figure 1, the elapsed fraction at t = 10 ms would be .25 |
| 136 | because the total duration is t = 40 ms.</p> |
| 137 | |
| 138 | <p>When the {@link android.animation.ValueAnimator} is done calculating an elapsed fraction, it |
| 139 | calls the {@link android.animation.TimeInterpolator} that is currently set, to calculate an |
| 140 | <em>interpolated fraction</em>. An interpolated fraction maps the elapsed fraction to a new |
| 141 | fraction that takes into account the time interpolation that is set. For example, in Figure 2, |
| 142 | because the animation slowly accelerates, the interpolated fraction, about .15, is less than the |
| 143 | elapsed fraction, .25, at t = 10 ms. In Figure 1, the interpolated fraction is always the same as |
| 144 | the elapsed fraction.</p> |
| 145 | |
| 146 | <p>When the interpolated fraction is calculated, {@link android.animation.ValueAnimator} calls |
| 147 | the appropriate {@link android.animation.TypeEvaluator}, to calculate the value of the |
| 148 | property that you are animating, based on the interpolated fraction, the starting value, and the |
| 149 | ending value of the animation. For example, in Figure 2, the interpolated fraction was .15 at t = |
| 150 | 10 ms, so the value for the property at that time would be .15 X (40 - 0), or 6.</p> |
| 151 | |
| 152 | <!-- <p>When the final value is calculated, the {@link android.animation.ValueAnimator} calls the |
| 153 | {@link android.animation.ValueAnimator.AnimatorUpdateListener#onAnimationUpdate |
| 154 | onAnimationUpdate()} method. Implement this callback to obtain the property value by |
| 155 | calling {@link android.animation.ValueAnimator#getAnimatedValue getAnimatedValue()} and set the |
| 156 | value for the property in the object that you are animating. Setting the property doesn't redraw |
| 157 | the object on the screen, so you need to call {@link |
| 158 | android.view.View#invalidate invalidate()} to refresh the View that the object |
| 159 | resides in. If the object is actually a View object, then the system calls {@link |
| 160 | android.view.View#invalidate invalidate()} when the property is changed. |
| 161 | The system redraws the window and the {@link android.animation.ValueAnimator} |
| 162 | repeats the process.</p>--> |
| 163 | |
| 164 | <p>The <code>com.example.android.apis.animation</code> package in the <a href= |
| 165 | "{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/animation/index.html">API |
| 166 | Demos</a> sample project provides many examples on how to use the property |
| 167 | animation system.</p> |
Scott Main | 50e990c | 2012-06-21 17:14:39 -0700 | [diff] [blame] | 168 | |
| 169 | <h2 id="property-vs-view">How Property Animation Differs from View Animation</h2> |
| 170 | |
| 171 | <p>The view animation system provides the capability to only animate {@link android.view.View} |
| 172 | objects, so if you wanted to animate non-{@link android.view.View} objects, you have to implement |
| 173 | your own code to do so. The view animation system is also constrained in the fact that it only |
| 174 | exposes a few aspects of a {@link android.view.View} object to animate, such as the scaling and |
| 175 | rotation of a View but not the background color, for instance.</p> |
| 176 | |
| 177 | <p>Another disadvantage of the view animation system is that it only modified where the |
| 178 | View was drawn, and not the actual View itself. For instance, if you animated a button to move |
| 179 | across the screen, the button draws correctly, but the actual location where you can click the |
| 180 | button does not change, so you have to implement your own logic to handle this.</p> |
| 181 | |
| 182 | <p>With the property animation system, these constraints are completely removed, and you can animate |
| 183 | any property of any object (Views and non-Views) and the object itself is actually modified. |
| 184 | The property animation system is also more robust in the way it carries out animation. At |
| 185 | a high level, you assign animators to the properties that you want to animate, such as color, |
| 186 | position, or size and can define aspects of the animation such as interpolation and |
| 187 | synchronization of multiple animators.</p> |
| 188 | |
| 189 | <p>The view animation system, however, takes less time to setup and requires less code to write. |
| 190 | If view animation accomplishes everything that you need to do, or if your existing code already |
| 191 | works the way you want, there is no need to use the property animation system. It also might |
| 192 | make sense to use both animation systems for different situations if the use case arises.</p> |
Robert Ly | 4b3e912 | 2011-09-15 15:09:17 -0700 | [diff] [blame] | 193 | |
| 194 | <h2>API Overview</h2> |
| 195 | |
| 196 | <p>You can find most of the property animation system's APIs in {@link android.animation |
| 197 | android.animation}. Because the view animation system already |
| 198 | defines many interpolators in {@link android.view.animation android.view.animation}, you can use |
| 199 | those interpolators in the property animation system as well. The following tables describe the main |
| 200 | components of the property animation system.</p> |
| 201 | |
| 202 | <p>The {@link android.animation.Animator} class provides the basic structure for creating |
| 203 | animations. You normally do not use this class directly as it only provides minimal |
| 204 | functionality that must be extended to fully support animating values. The following |
| 205 | subclasses extend {@link android.animation.Animator}: |
| 206 | </p> |
| 207 | <p class="table-caption"><strong>Table 1.</strong> Animators</p> |
| 208 | <table> |
| 209 | <tr> |
| 210 | <th>Class</th> |
| 211 | |
| 212 | <th>Description</th> |
| 213 | </tr> |
| 214 | |
| 215 | <tr> |
| 216 | <td>{@link android.animation.ValueAnimator}</td> |
| 217 | |
| 218 | <td>The main timing engine for property animation that also computes the values for the |
| 219 | property to be animated. It has all of the core functionality that calculates animation |
| 220 | values and contains the timing details of each animation, information about whether an |
| 221 | animation repeats, listeners that receive update events, and the ability to set custom |
| 222 | types to evaluate. There are two pieces to animating properties: calculating the animated |
| 223 | values and setting those values on the object and property that is being animated. {@link |
| 224 | android.animation.ValueAnimator} does not carry out the second piece, so you must listen |
| 225 | for updates to values calculated by the {@link android.animation.ValueAnimator} and |
| 226 | modify the objects that you want to animate with your own logic. See the section about |
| 227 | <a href="#value-animator">Animating with ValueAnimator</a> for more information.</td> |
| 228 | </tr> |
| 229 | |
| 230 | <tr> |
| 231 | <td>{@link android.animation.ObjectAnimator}</td> |
| 232 | |
| 233 | <td>A subclass of {@link android.animation.ValueAnimator} that allows you to set a target |
| 234 | object and object property to animate. This class updates the property accordingly when |
| 235 | it computes a new value for the animation. You want to use |
| 236 | {@link android.animation.ObjectAnimator} most of the time, |
| 237 | because it makes the process of animating values on target objects much easier. However, |
| 238 | you sometimes want to use {@link android.animation.ValueAnimator} directly because {@link |
| 239 | android.animation.ObjectAnimator} has a few more restrictions, such as requiring specific |
| 240 | acessor methods to be present on the target object.</td> |
| 241 | </tr> |
| 242 | |
| 243 | <tr> |
| 244 | <td>{@link android.animation.AnimatorSet}</td> |
| 245 | |
| 246 | <td>Provides a mechanism to group animations together so that they run in |
| 247 | relation to one another. You can set animations to play together, sequentially, or after |
| 248 | a specified delay. See the section about <a href="#choreography">Choreographing multiple |
| 249 | animations with Animator Sets</a> for more information.</td> |
| 250 | </tr> |
| 251 | </table> |
| 252 | |
| 253 | |
| 254 | <p>Evaluators tell the property animation system how to calculate values for a given |
| 255 | property. They take the timing data that is provided by an {@link android.animation.Animator} |
| 256 | class, the animation's start and end value, and calculate the animated values of the property |
| 257 | based on this data. The property animation system provides the following evaluators:</p> |
| 258 | <p class="table-caption"><strong>Table 2.</strong> Evaluators</p> |
| 259 | <table> |
| 260 | <tr> |
| 261 | <th>Class/Interface</th> |
| 262 | |
| 263 | <th>Description</th> |
| 264 | </tr> |
| 265 | |
| 266 | <tr> |
| 267 | <td>{@link android.animation.IntEvaluator}</td> |
| 268 | |
| 269 | <td>The default evaluator to calculate values for <code>int</code> properties.</td> |
| 270 | </tr> |
| 271 | |
| 272 | <tr> |
| 273 | <td>{@link android.animation.FloatEvaluator}</td> |
| 274 | |
| 275 | <td>The default evaluator to calculate values for <code>float</code> properties.</td> |
| 276 | </tr> |
| 277 | |
| 278 | <tr> |
| 279 | <td>{@link android.animation.ArgbEvaluator}</td> |
| 280 | |
| 281 | <td>The default evaluator to calculate values for color properties that are represented |
| 282 | as hexidecimal values.</td> |
| 283 | </tr> |
| 284 | |
| 285 | <tr> |
| 286 | <td>{@link android.animation.TypeEvaluator}</td> |
| 287 | |
| 288 | <td>An interface that allows you to create your own evaluator. If you are animating an |
| 289 | object property that is <em>not</em> an <code>int</code>, <code>float</code>, or color, |
| 290 | you must implement the {@link android.animation.TypeEvaluator} interface to specify how |
| 291 | to compute the object property's animated values. You can also specify a custom {@link |
| 292 | android.animation.TypeEvaluator} for <code>int</code>, <code>float</code>, and color |
| 293 | values as well, if you want to process those types differently than the default behavior. |
| 294 | See the section about <a href="#type-evaluator">Using a TypeEvaluator</a> for more |
| 295 | information on how to write a custom evaluator.</td> |
| 296 | </tr> |
| 297 | </table> |
| 298 | |
| 299 | |
| 300 | |
| 301 | |
| 302 | <p>A time interpolator defines how specific values in an animation are calculated as a |
| 303 | function of time. For example, you can specify animations to happen linearly across the whole |
| 304 | animation, meaning the animation moves evenly the entire time, or you can specify animations |
| 305 | to use non-linear time, for example, accelerating at the beginning and decelerating at the |
| 306 | end of the animation. Table 3 describes the interpolators that are contained in {@link |
| 307 | android.view.animation android.view.animation}. If none of the provided interpolators suits |
| 308 | your needs, implement the {@link android.animation.TimeInterpolator} interface and create your own. See <a href= |
| 309 | "#interpolators">Using interpolators</a> for more information on how to write a custom |
| 310 | interpolator.</p> |
| 311 | <p class="table-caption"><strong>Table 3.</strong> Interpolators</p> |
| 312 | <table> |
| 313 | <tr> |
| 314 | <th>Class/Interface</th> |
| 315 | |
| 316 | <th>Description</th> |
| 317 | </tr> |
| 318 | |
| 319 | <tr> |
| 320 | <td>{@link android.view.animation.AccelerateDecelerateInterpolator}</td> |
| 321 | |
| 322 | <td>An interpolator whose rate of change starts and ends slowly but accelerates |
| 323 | through the middle.</td> |
| 324 | </tr> |
| 325 | |
| 326 | <tr> |
| 327 | <td>{@link android.view.animation.AccelerateInterpolator}</td> |
| 328 | |
| 329 | <td>An interpolator whose rate of change starts out slowly and then |
| 330 | accelerates.</td> |
| 331 | </tr> |
| 332 | |
| 333 | <tr> |
| 334 | <td>{@link android.view.animation.AnticipateInterpolator}</td> |
| 335 | |
| 336 | <td>An interpolator whose change starts backward then flings forward.</td> |
| 337 | </tr> |
| 338 | |
| 339 | <tr> |
| 340 | <td>{@link android.view.animation.AnticipateOvershootInterpolator}</td> |
| 341 | |
| 342 | <td>An interpolator whose change starts backward, flings forward and overshoots |
| 343 | the target value, then finally goes back to the final value.</td> |
| 344 | </tr> |
| 345 | |
| 346 | <tr> |
| 347 | <td>{@link android.view.animation.BounceInterpolator}</td> |
| 348 | |
| 349 | <td>An interpolator whose change bounces at the end.</td> |
| 350 | </tr> |
| 351 | |
| 352 | <tr> |
| 353 | <td>{@link android.view.animation.CycleInterpolator}</td> |
| 354 | |
| 355 | <td>An interpolator whose animation repeats for a specified number of cycles.</td> |
| 356 | </tr> |
| 357 | |
| 358 | <tr> |
| 359 | <td>{@link android.view.animation.DecelerateInterpolator}</td> |
| 360 | |
| 361 | <td>An interpolator whose rate of change starts out quickly and and then |
| 362 | decelerates.</td> |
| 363 | </tr> |
| 364 | |
| 365 | <tr> |
| 366 | <td>{@link android.view.animation.LinearInterpolator}</td> |
| 367 | |
| 368 | <td>An interpolator whose rate of change is constant.</td> |
| 369 | </tr> |
| 370 | |
| 371 | <tr> |
| 372 | <td>{@link android.view.animation.OvershootInterpolator}</td> |
| 373 | |
| 374 | <td>An interpolator whose change flings forward and overshoots the last value then |
| 375 | comes back.</td> |
| 376 | </tr> |
| 377 | |
| 378 | <tr> |
| 379 | <td>{@link android.animation.TimeInterpolator}</td> |
| 380 | |
| 381 | <td>An interface that allows you to implement your own interpolator.</td> |
| 382 | </tr> |
| 383 | </table> |
| 384 | |
| 385 | <h2 id="value-animator">Animating with ValueAnimator</h2> |
| 386 | |
| 387 | <p>The {@link android.animation.ValueAnimator} class lets you animate values of some type for the |
| 388 | duration of an animation by specifying a set of <code>int</code>, <code>float</code>, or color |
| 389 | values to animate through. You obtain a {@link android.animation.ValueAnimator} by calling one of |
| 390 | its factory methods: {@link android.animation.ValueAnimator#ofInt ofInt()}, {@link |
| 391 | android.animation.ValueAnimator#ofFloat ofFloat()}, or {@link |
| 392 | android.animation.ValueAnimator#ofObject ofObject()}. For example:</p> |
| 393 | <pre> |
| 394 | ValueAnimator animation = ValueAnimator.ofFloat(0f, 1f); |
| 395 | animation.setDuration(1000); |
| 396 | animation.start(); |
| 397 | </pre> |
| 398 | |
| 399 | <p>In this code, the {@link android.animation.ValueAnimator} starts calculating the values of the |
| 400 | animation, between 0 and 1, for a duration of 1000 ms, when the <code>start()</code> method |
| 401 | runs.</p> |
| 402 | |
| 403 | <p>You can also specify a custom type to animate by doing the following:</p> |
| 404 | <pre> |
| 405 | ValueAnimator animation = ValueAnimator.ofObject(new MyTypeEvaluator(), startPropertyValue, endPropertyValue); |
| 406 | animation.setDuration(1000); |
| 407 | animation.start(); |
| 408 | </pre> |
| 409 | |
| 410 | <p>In this code, the {@link android.animation.ValueAnimator} starts calculating the values of the |
| 411 | animation, between <code>startPropertyValue</code> and <code>endPropertyValue</code> using the |
| 412 | logic supplied by <code>MyTypeEvaluator</code> for a duration of 1000 ms, when the {@link |
| 413 | android.animation.ValueAnimator#start start()} method runs.</p> |
| 414 | |
| 415 | <p>The previous code snippets, however, has no real effect on an object, because the {@link |
| 416 | android.animation.ValueAnimator} does not operate on objects or properties directly. The most likely thing |
| 417 | that you want to do is modify the objects that you want to animate with these calculated values. You do |
| 418 | this by defining listeners in the {@link android.animation.ValueAnimator} to appropriately handle important events |
| 419 | during the animation's lifespan, such as frame updates. When implementing the listeners, you can |
| 420 | obtain the calculated value for that specific frame refresh by calling {@link |
| 421 | android.animation.ValueAnimator#getAnimatedValue getAnimatedValue()}. For more information on listeners, |
| 422 | see the section about <a href="#listeners">Animation Listeners</a>. |
| 423 | |
| 424 | <h2 id="object-animator">Animating with ObjectAnimator</h2> |
| 425 | |
| 426 | <p>The {@link android.animation.ObjectAnimator} is a subclass of the {@link |
| 427 | android.animation.ValueAnimator} (discussed in the previous section) and combines the timing |
| 428 | engine and value computation of {@link android.animation.ValueAnimator} with the ability to |
| 429 | animate a named property of a target object. This makes animating any object much easier, as you |
| 430 | no longer need to implement the {@link android.animation.ValueAnimator.AnimatorUpdateListener}, |
| 431 | because the animated property updates automatically.</p> |
| 432 | |
| 433 | <p>Instantiating an {@link android.animation.ObjectAnimator} is similar to a {@link |
| 434 | android.animation.ValueAnimator}, but you also specify the object and the name of that object's property (as |
| 435 | a String) along with the values to animate between:</p> |
| 436 | <pre> |
| 437 | ObjectAnimator anim = ObjectAnimator.ofFloat(foo, "alpha", 0f, 1f); |
| 438 | anim.setDuration(1000); |
| 439 | anim.start(); |
| 440 | </pre> |
| 441 | |
| 442 | <p>To have the {@link android.animation.ObjectAnimator} update properties correctly, you must do |
| 443 | the following:</p> |
| 444 | |
| 445 | <ul> |
| 446 | <li>The object property that you are animating must have a setter function (in camel case) in the form of |
| 447 | <code>set<propertyName>()</code>. Because the {@link android.animation.ObjectAnimator} |
| 448 | automatically updates the property during animation, it must be able to access the property |
| 449 | with this setter method. For example, if the property name is <code>foo</code>, you need to |
| 450 | have a <code>setFoo()</code> method. If this setter method does not exist, you have three |
| 451 | options: |
| 452 | |
| 453 | <ul> |
| 454 | <li>Add the setter method to the class if you have the rights to do so.</li> |
| 455 | |
| 456 | <li>Use a wrapper class that you have rights to change and have that wrapper receive the |
| 457 | value with a valid setter method and forward it to the original object.</li> |
| 458 | |
| 459 | <li>Use {@link android.animation.ValueAnimator} instead.</li> |
| 460 | </ul> |
| 461 | </li> |
| 462 | |
| 463 | <li>If you specify only one value for the <code>values...</code> parameter in one of the {@link |
| 464 | android.animation.ObjectAnimator} factory methods, it is assumed to be the ending value of the |
| 465 | animation. Therefore, the object property that you are animating must have a getter function |
| 466 | that is used to obtain the starting value of the animation. The getter function must be in the |
| 467 | form of <code>get<propertyName>()</code>. For example, if the property name is |
| 468 | <code>foo</code>, you need to have a <code>getFoo()</code> method.</li> |
| 469 | |
| 470 | <li>The getter (if needed) and setter methods of the property that you are animating must |
| 471 | operate on the same type as the starting and ending values that you specify to {@link |
| 472 | android.animation.ObjectAnimator}. For example, you must have |
| 473 | <code>targetObject.setPropName(float)</code> and <code>targetObject.getPropName(float)</code> |
| 474 | if you construct the following {@link android.animation.ObjectAnimator}: |
| 475 | <pre> |
| 476 | ObjectAnimator.ofFloat(targetObject, "propName", 1f) |
| 477 | </pre> |
| 478 | </li> |
| 479 | |
| 480 | <li>Depending on what property or object you are animating, you might need to call the {@link |
kmccormick | 3b9f0aa | 2013-04-01 18:08:28 -0700 | [diff] [blame] | 481 | android.view.View#invalidate invalidate()} method on a View to force the screen to redraw itself with the |
Robert Ly | 4b3e912 | 2011-09-15 15:09:17 -0700 | [diff] [blame] | 482 | updated animated values. You do this in the |
| 483 | {@link android.animation.ValueAnimator.AnimatorUpdateListener#onAnimationUpdate onAnimationUpdate()} |
| 484 | callback. For example, animating the color property of a Drawable object only cause updates to the |
| 485 | screen when that object redraws itself. All of the property setters on View, such as |
| 486 | {@link android.view.View#setAlpha setAlpha()} and {@link android.view.View#setTranslationX setTranslationX()} |
| 487 | invalidate the View properly, so you do not need to invalidate the View when calling these |
| 488 | methods with new values. For more information on listeners, see the section about <a href="#listeners">Animation Listeners</a>. |
| 489 | </li> |
| 490 | </ul> |
| 491 | |
| 492 | <h2 id="choreography">Choreographing Multiple Animations with AnimatorSet</h2> |
| 493 | |
| 494 | <p>In many cases, you want to play an animation that depends on when another animation starts or |
| 495 | finishes. The Android system lets you bundle animations together into an {@link |
| 496 | android.animation.AnimatorSet}, so that you can specify whether to start animations |
| 497 | simultaneously, sequentially, or after a specified delay. You can also nest {@link |
| 498 | android.animation.AnimatorSet} objects within each other.</p> |
| 499 | |
| 500 | <p>The following sample code taken from the <a href= |
| 501 | "{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/animation/BouncingBalls.html">Bouncing |
| 502 | Balls</a> sample (modified for simplicity) plays the following {@link android.animation.Animator} |
| 503 | objects in the following manner:</p> |
| 504 | |
| 505 | <ol> |
| 506 | <li>Plays <code>bounceAnim</code>.</li> |
| 507 | |
| 508 | <li>Plays <code>squashAnim1</code>, <code>squashAnim2</code>, <code>stretchAnim1</code>, and |
| 509 | <code>stretchAnim2</code> at the same time.</li> |
| 510 | |
| 511 | <li>Plays <code>bounceBackAnim</code>.</li> |
| 512 | |
| 513 | <li>Plays <code>fadeAnim</code>.</li> |
| 514 | </ol> |
| 515 | <pre> |
| 516 | AnimatorSet bouncer = new AnimatorSet(); |
| 517 | bouncer.play(bounceAnim).before(squashAnim1); |
| 518 | bouncer.play(squashAnim1).with(squashAnim2); |
| 519 | bouncer.play(squashAnim1).with(stretchAnim1); |
| 520 | bouncer.play(squashAnim1).with(stretchAnim2); |
| 521 | bouncer.play(bounceBackAnim).after(stretchAnim2); |
| 522 | ValueAnimator fadeAnim = ObjectAnimator.ofFloat(newBall, "alpha", 1f, 0f); |
| 523 | fadeAnim.setDuration(250); |
| 524 | AnimatorSet animatorSet = new AnimatorSet(); |
| 525 | animatorSet.play(bouncer).before(fadeAnim); |
| 526 | animatorSet.start(); |
| 527 | </pre> |
| 528 | |
| 529 | <p>For a more complete example on how to use animator sets, see the <a href= |
| 530 | "{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/animation/BouncingBalls.html">Bouncing |
| 531 | Balls</a> sample in APIDemos.</p> |
| 532 | |
| 533 | <h2 id="listeners">Animation Listeners</h2> |
| 534 | <p> |
| 535 | You can listen for important events during an animation's duration with the listeners described below. |
| 536 | </p> |
| 537 | |
| 538 | <ul> |
| 539 | <li>{@link android.animation.Animator.AnimatorListener} |
| 540 | |
| 541 | <ul> |
| 542 | <li>{@link android.animation.Animator.AnimatorListener#onAnimationStart onAnimationStart()} |
| 543 | - Called when the animation starts.</li> |
| 544 | |
| 545 | <li>{@link android.animation.Animator.AnimatorListener#onAnimationEnd onAnimationEnd()} - |
| 546 | Called when the animation ends.</li> |
| 547 | |
| 548 | <li>{@link android.animation.Animator.AnimatorListener#onAnimationRepeat |
| 549 | onAnimationRepeat()} - Called when the animation repeats itself.</li> |
| 550 | |
| 551 | <li>{@link android.animation.Animator.AnimatorListener#onAnimationCancel |
| 552 | onAnimationCancel()} - Called when the animation is canceled. A cancelled animation |
| 553 | also calls {@link android.animation.Animator.AnimatorListener#onAnimationEnd onAnimationEnd()}, |
| 554 | regardless of how they were ended.</li> |
| 555 | </ul> |
| 556 | </li> |
| 557 | |
| 558 | <li>{@link android.animation.ValueAnimator.AnimatorUpdateListener} |
| 559 | |
| 560 | <ul> |
| 561 | <li> |
| 562 | <p>{@link android.animation.ValueAnimator.AnimatorUpdateListener#onAnimationUpdate |
| 563 | onAnimationUpdate()} - called on every frame of the animation. Listen to this event to |
| 564 | use the calculated values generated by {@link android.animation.ValueAnimator} during an |
| 565 | animation. To use the value, query the {@link android.animation.ValueAnimator} object |
| 566 | passed into the event to get the current animated value with the {@link |
| 567 | android.animation.ValueAnimator#getAnimatedValue getAnimatedValue()} method. Implementing this |
| 568 | listener is required if you use {@link android.animation.ValueAnimator}. </p> |
| 569 | |
| 570 | <p> |
| 571 | Depending on what property or object you are animating, you might need to call |
| 572 | {@link android.view.View#invalidate invalidate()} on a View to force that area of the |
| 573 | screen to redraw itself with the new animated values. For example, animating the |
| 574 | color property of a Drawable object only cause updates to the screen when that object |
| 575 | redraws itself. All of the property setters on View, |
| 576 | such as {@link android.view.View#setAlpha setAlpha()} and |
| 577 | {@link android.view.View#setTranslationX setTranslationX()} invalidate the View |
| 578 | properly, so you do not need to invalidate the View when calling these methods with new values. |
| 579 | </p> |
| 580 | |
| 581 | </li> |
| 582 | </ul> |
| 583 | </li> |
| 584 | </ul> |
| 585 | |
| 586 | <p>You can extend the {@link android.animation.AnimatorListenerAdapter} class instead of |
| 587 | implementing the {@link android.animation.Animator.AnimatorListener} interface, if you do not |
| 588 | want to implement all of the methods of the {@link android.animation.Animator.AnimatorListener} |
| 589 | interface. The {@link android.animation.AnimatorListenerAdapter} class provides empty |
| 590 | implementations of the methods that you can choose to override.</p> |
| 591 | <p>For example, the <a href= |
| 592 | "{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/animation/BouncingBalls.html">Bouncing |
| 593 | Balls</a> sample in the API demos creates an {@link android.animation.AnimatorListenerAdapter} |
| 594 | for just the {@link android.animation.Animator.AnimatorListener#onAnimationEnd onAnimationEnd()} |
| 595 | callback:</p> |
| 596 | <pre> |
| 597 | ValueAnimatorAnimator fadeAnim = ObjectAnimator.ofFloat(newBall, "alpha", 1f, 0f); |
| 598 | fadeAnim.setDuration(250); |
| 599 | fadeAnim.addListener(new AnimatorListenerAdapter() { |
| 600 | public void onAnimationEnd(Animator animation) { |
| 601 | balls.remove(((ObjectAnimator)animation).getTarget()); |
| 602 | } |
| 603 | </pre> |
| 604 | |
| 605 | |
| 606 | <h2 id="layout">Animating Layout Changes to ViewGroups</h2> |
| 607 | |
| 608 | <p>The property animation system provides the capability to animate changes to ViewGroup objects |
| 609 | as well as provide an easy way to animate View objects themselves.</p> |
| 610 | |
| 611 | <p>You can animate layout changes within a ViewGroup with the {@link |
| 612 | android.animation.LayoutTransition} class. Views inside a ViewGroup can go through an appearing |
| 613 | and disappearing animation when you add them to or remove them from a ViewGroup or when you call |
| 614 | a View's {@link android.view.View#setVisibility setVisibility()} method with {@link |
| 615 | android.view.View#VISIBLE}, android.view.View#INVISIBLE}, or {@link android.view.View#GONE}. The remaining Views in the |
| 616 | ViewGroup can also animate into their new positions when you add or remove Views. You can define |
| 617 | the following animations in a {@link android.animation.LayoutTransition} object by calling {@link |
| 618 | android.animation.LayoutTransition#setAnimator setAnimator()} and passing in an {@link |
| 619 | android.animation.Animator} object with one of the following {@link |
| 620 | android.animation.LayoutTransition} constants:</p> |
| 621 | |
| 622 | <ul> |
| 623 | <li><code>APPEARING</code> - A flag indicating the animation that runs on items that are |
| 624 | appearing in the container.</li> |
| 625 | |
| 626 | <li><code>CHANGE_APPEARING</code> - A flag indicating the animation that runs on items that are |
| 627 | changing due to a new item appearing in the container.</li> |
| 628 | |
| 629 | <li><code>DISAPPEARING</code> - A flag indicating the animation that runs on items that are |
| 630 | disappearing from the container.</li> |
| 631 | |
| 632 | <li><code>CHANGE_DISAPPEARING</code> - A flag indicating the animation that runs on items that |
| 633 | are changing due to an item disappearing from the container.</li> |
| 634 | </ul> |
| 635 | |
| 636 | <p>You can define your own custom animations for these four types of events to customize the look |
| 637 | of your layout transitions or just tell the animation system to use the default animations.</p> |
| 638 | |
| 639 | <p>The <a href= |
| 640 | "{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/animation/LayoutAnimations.html"> |
| 641 | LayoutAnimations</a> sample in API Demos shows you how to define animations for layout |
| 642 | transitions and then set the animations on the View objects that you want to animate.</p> |
| 643 | |
| 644 | <p>The <a href= |
| 645 | "{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/animation/LayoutAnimationsByDefault.html"> |
| 646 | LayoutAnimationsByDefault</a> and its corresponding <a href= |
| 647 | "{@docRoot}resources/samples/ApiDemos/res/layout/layout_animations_by_default.html">layout_animations_by_default.xml</a> |
| 648 | layout resource file show you how to enable the default layout transitions for ViewGroups in XML. |
| 649 | The only thing that you need to do is to set the <code>android:animateLayoutchanges</code> |
| 650 | attribute to <code>true</code> for the ViewGroup. For example:</p> |
| 651 | <pre> |
| 652 | <LinearLayout |
| 653 | android:orientation="vertical" |
| 654 | android:layout_width="wrap_content" |
| 655 | android:layout_height="match_parent" |
| 656 | android:id="@+id/verticalContainer" |
| 657 | android:animateLayoutChanges="true" /> |
| 658 | </pre> |
| 659 | |
| 660 | <p>Setting this attribute to true automatically animates Views that are added or removed from the |
| 661 | ViewGroup as well as the remaining Views in the ViewGroup.</p> |
| 662 | |
| 663 | <h2 id="type-evaluator">Using a TypeEvaluator</h2> |
| 664 | |
| 665 | <p>If you want to animate a type that is unknown to the Android system, you can create your own |
| 666 | evaluator by implementing the {@link android.animation.TypeEvaluator} interface. The types that |
| 667 | are known by the Android system are <code>int</code>, <code>float</code>, or a color, which are |
| 668 | supported by the {@link android.animation.IntEvaluator}, {@link |
| 669 | android.animation.FloatEvaluator}, and {@link android.animation.ArgbEvaluator} type |
| 670 | evaluators.</p> |
| 671 | |
| 672 | <p>There is only one method to implement in the {@link android.animation.TypeEvaluator} |
| 673 | interface, the {@link android.animation.TypeEvaluator#evaluate evaluate()} method. This allows |
| 674 | the animator that you are using to return an appropriate value for your animated property at the |
| 675 | current point of the animation. The {@link android.animation.FloatEvaluator} class demonstrates |
| 676 | how to do this:</p> |
| 677 | <pre> |
| 678 | public class FloatEvaluator implements TypeEvaluator { |
| 679 | |
| 680 | public Object evaluate(float fraction, Object startValue, Object endValue) { |
| 681 | float startFloat = ((Number) startValue).floatValue(); |
| 682 | return startFloat + fraction * (((Number) endValue).floatValue() - startFloat); |
| 683 | } |
| 684 | } |
| 685 | </pre> |
| 686 | |
| 687 | <p class="note"><strong>Note:</strong> When {@link android.animation.ValueAnimator} (or {@link |
| 688 | android.animation.ObjectAnimator}) runs, it calculates a current elapsed fraction of the |
| 689 | animation (a value between 0 and 1) and then calculates an interpolated version of that depending |
| 690 | on what interpolator that you are using. The interpolated fraction is what your {@link |
| 691 | android.animation.TypeEvaluator} receives through the <code>fraction</code> parameter, so you do |
| 692 | not have to take into account the interpolator when calculating animated values.</p> |
| 693 | |
| 694 | <h2 id="interpolators">Using Interpolators</h2> |
| 695 | |
| 696 | <p>An interpolator define how specific values in an animation are calculated as a function of |
| 697 | time. For example, you can specify animations to happen linearly across the whole animation, |
| 698 | meaning the animation moves evenly the entire time, or you can specify animations to use |
| 699 | non-linear time, for example, using acceleration or deceleration at the beginning or end of the |
| 700 | animation.</p> |
| 701 | |
| 702 | <p>Interpolators in the animation system receive a fraction from Animators that represent the |
| 703 | elapsed time of the animation. Interpolators modify this fraction to coincide with the type of |
| 704 | animation that it aims to provide. The Android system provides a set of common interpolators in |
| 705 | the {@link android.view.animation android.view.animation package}. If none of these suit your |
| 706 | needs, you can implement the {@link android.animation.TimeInterpolator} interface and create your |
| 707 | own.</p> |
| 708 | |
| 709 | <p>As an example, how the default interpolator {@link |
| 710 | android.view.animation.AccelerateDecelerateInterpolator} and the {@link |
| 711 | android.view.animation.LinearInterpolator} calculate interpolated fractions are compared below. |
| 712 | The {@link android.view.animation.LinearInterpolator} has no effect on the elapsed fraction. The {@link |
| 713 | android.view.animation.AccelerateDecelerateInterpolator} accelerates into the animation and |
| 714 | decelerates out of it. The following methods define the logic for these interpolators:</p> |
| 715 | |
| 716 | <p><strong>AccelerateDecelerateInterpolator</strong></p> |
| 717 | <pre> |
| 718 | public float getInterpolation(float input) { |
| 719 | return (float)(Math.cos((input + 1) * Math.PI) / 2.0f) + 0.5f; |
| 720 | } |
| 721 | </pre> |
| 722 | |
| 723 | <p><strong>LinearInterpolator</strong></p> |
| 724 | <pre> |
| 725 | public float getInterpolation(float input) { |
| 726 | return input; |
| 727 | } |
| 728 | </pre> |
| 729 | |
| 730 | <p>The following table represents the approximate values that are calculated by these |
| 731 | interpolators for an animation that lasts 1000ms:</p> |
| 732 | |
| 733 | <table> |
| 734 | <tr> |
| 735 | <th>ms elapsed</th> |
| 736 | |
| 737 | <th>Elapsed fraction/Interpolated fraction (Linear)</th> |
| 738 | |
| 739 | <th>Interpolated fraction (Accelerate/Decelerate)</th> |
| 740 | </tr> |
| 741 | |
| 742 | <tr> |
| 743 | <td>0</td> |
| 744 | |
| 745 | <td>0</td> |
| 746 | |
| 747 | <td>0</td> |
| 748 | </tr> |
| 749 | |
| 750 | <tr> |
| 751 | <td>200</td> |
| 752 | |
| 753 | <td>.2</td> |
| 754 | |
| 755 | <td>.1</td> |
| 756 | </tr> |
| 757 | |
| 758 | <tr> |
| 759 | <td>400</td> |
| 760 | |
| 761 | <td>.4</td> |
| 762 | |
| 763 | <td>.345</td> |
| 764 | </tr> |
| 765 | |
| 766 | <tr> |
| 767 | <td>600</td> |
| 768 | |
| 769 | <td>.6</td> |
| 770 | |
| 771 | <td>.8</td> |
| 772 | </tr> |
| 773 | |
| 774 | <tr> |
| 775 | <td>800</td> |
| 776 | |
| 777 | <td>.8</td> |
| 778 | |
| 779 | <td>.9</td> |
| 780 | </tr> |
| 781 | |
| 782 | <tr> |
| 783 | <td>1000</td> |
| 784 | |
| 785 | <td>1</td> |
| 786 | |
| 787 | <td>1</td> |
| 788 | </tr> |
| 789 | </table> |
| 790 | |
| 791 | <p>As the table shows, the {@link android.view.animation.LinearInterpolator} changes the values |
| 792 | at the same speed, .2 for every 200ms that passes. The {@link |
| 793 | android.view.animation.AccelerateDecelerateInterpolator} changes the values faster than {@link |
| 794 | android.view.animation.LinearInterpolator} between 200ms and 600ms and slower between 600ms and |
| 795 | 1000ms.</p> |
| 796 | |
| 797 | <h2 id="keyframes">Specifying Keyframes</h2> |
| 798 | |
| 799 | <p>A {@link android.animation.Keyframe} object consists of a time/value pair that lets you define |
| 800 | a specific state at a specific time of an animation. Each keyframe can also have its own |
| 801 | interpolator to control the behavior of the animation in the interval between the previous |
| 802 | keyframe's time and the time of this keyframe.</p> |
| 803 | |
| 804 | <p>To instantiate a {@link android.animation.Keyframe} object, you must use one of the factory |
| 805 | methods, {@link android.animation.Keyframe#ofInt ofInt()}, {@link |
| 806 | android.animation.Keyframe#ofFloat ofFloat()}, or {@link android.animation.Keyframe#ofObject |
| 807 | ofObject()} to obtain the appropriate type of {@link android.animation.Keyframe}. You then call |
| 808 | the {@link android.animation.PropertyValuesHolder#ofKeyframe ofKeyframe()} factory method to |
| 809 | obtain a {@link android.animation.PropertyValuesHolder} object. Once you have the object, you can |
| 810 | obtain an animator by passing in the {@link android.animation.PropertyValuesHolder} object and |
| 811 | the object to animate. The following code snippet demonstrates how to do this:</p> |
| 812 | <pre> |
| 813 | Keyframe kf0 = Keyframe.ofFloat(0f, 0f); |
| 814 | Keyframe kf1 = Keyframe.ofFloat(.5f, 360f); |
| 815 | Keyframe kf2 = Keyframe.ofFloat(1f, 0f); |
| 816 | PropertyValuesHolder pvhRotation = PropertyValuesHolder.ofKeyframe("rotation", kf0, kf1, kf2); |
| 817 | ObjectAnimator rotationAnim = ObjectAnimator.ofPropertyValuesHolder(target, pvhRotation) |
| 818 | rotationAnim.setDuration(5000ms); |
| 819 | </pre> |
| 820 | |
| 821 | <p>For a more complete example on how to use keyframes, see the <a href= |
| 822 | "{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/animation/MultiPropertyAnimation.html"> |
| 823 | MultiPropertyAnimation</a> sample in APIDemos.</p> |
| 824 | |
| 825 | <h2 id="views">Animating Views</h2> |
| 826 | |
kmccormick | 3b9f0aa | 2013-04-01 18:08:28 -0700 | [diff] [blame] | 827 | <p>The property animation system allow streamlined animation of View objects and offers |
Robert Ly | 4b3e912 | 2011-09-15 15:09:17 -0700 | [diff] [blame] | 828 | a few advantages over the view animation system. The view |
| 829 | animation system transformed View objects by changing the way that they were drawn. This was |
| 830 | handled in the container of each View, because the View itself had no properties to manipulate. |
| 831 | This resulted in the View being animated, but caused no change in the View object itself. This |
| 832 | led to behavior such as an object still existing in its original location, even though it was |
| 833 | drawn on a different location on the screen. In Android 3.0, new properties and the corresponding |
| 834 | getter and setter methods were added to eliminate this drawback.</p> |
| 835 | <p>The property animation system |
| 836 | can animate Views on the screen by changing the actual properties in the View objects. In |
| 837 | addition, Views also automatically call the {@link android.view.View#invalidate invalidate()} |
| 838 | method to refresh the screen whenever its properties are changed. The new properties in the {@link |
| 839 | android.view.View} class that facilitate property animations are:</p> |
| 840 | |
| 841 | <ul> |
| 842 | <li><code>translationX</code> and <code>translationY</code>: These properties control where the |
| 843 | View is located as a delta from its left and top coordinates which are set by its layout |
| 844 | container.</li> |
| 845 | |
| 846 | <li><code>rotation</code>, <code>rotationX</code>, and <code>rotationY</code>: These properties |
| 847 | control the rotation in 2D (<code>rotation</code> property) and 3D around the pivot point.</li> |
| 848 | |
| 849 | <li><code>scaleX</code> and <code>scaleY</code>: These properties control the 2D scaling of a |
| 850 | View around its pivot point.</li> |
| 851 | |
| 852 | <li><code>pivotX</code> and <code>pivotY</code>: These properties control the location of the |
| 853 | pivot point, around which the rotation and scaling transforms occur. By default, the pivot |
| 854 | point is located at the center of the object.</li> |
| 855 | |
| 856 | <li><code>x</code> and <code>y</code>: These are simple utility properties to describe the |
| 857 | final location of the View in its container, as a sum of the left and top values and |
| 858 | translationX and translationY values.</li> |
| 859 | |
| 860 | <li><code>alpha</code>: Represents the alpha transparency on the View. This value is 1 (opaque) |
| 861 | by default, with a value of 0 representing full transparency (not visible).</li> |
| 862 | </ul> |
| 863 | |
| 864 | <p>To animate a property of a View object, such as its color or rotation value, all you need to |
| 865 | do is create a property animator and specify the View property that you want to |
| 866 | animate. For example:</p> |
| 867 | <pre> |
| 868 | ObjectAnimator.ofFloat(myView, "rotation", 0f, 360f); |
| 869 | </pre> |
| 870 | |
| 871 | <p>For more information on creating animators, see the sections on animating with |
| 872 | <a href="#value-animator">ValueAnimator</a> and <a href="#object-animator">ObjectAnimator</a>. |
| 873 | </p> |
| 874 | |
| 875 | <h3 id="view-prop-animator">Animating with ViewPropertyAnimator</h3> |
| 876 | <p>The {@link android.view.ViewPropertyAnimator} provides a simple way to animate several |
| 877 | properties of a {@link android.view.View} in parallel, using a single underlying {@link |
| 878 | android.animation.Animator} |
| 879 | object. It behaves much like an {@link android.animation.ObjectAnimator}, because it modifies the |
| 880 | actual values of the view's properties, but is more efficient when animating many properties at |
| 881 | once. In addition, the code for using the {@link android.view.ViewPropertyAnimator} is much |
| 882 | more concise and easier to read. The following code snippets show the differences in using multiple |
| 883 | {@link android.animation.ObjectAnimator} objects, a single |
| 884 | {@link android.animation.ObjectAnimator}, and the {@link android.view.ViewPropertyAnimator} when |
| 885 | simultaneously animating the <code>x</code> and <code>y</code> property of a view.</p> |
| 886 | |
| 887 | <p><strong>Multiple ObjectAnimator objects</strong></p> |
| 888 | <pre> |
| 889 | ObjectAnimator animX = ObjectAnimator.ofFloat(myView, "x", 50f); |
| 890 | ObjectAnimator animY = ObjectAnimator.ofFloat(myView, "y", 100f); |
| 891 | AnimatorSet animSetXY = new AnimatorSet(); |
| 892 | animSetXY.playTogether(animX, animY); |
| 893 | animSetXY.start(); |
| 894 | </pre> |
| 895 | |
| 896 | <p><strong>One ObjectAnimator</strong></p> |
| 897 | <pre> |
| 898 | PropertyValuesHolder pvhX = PropertyValuesHolder.ofFloat("x", 50f); |
| 899 | PropertyValuesHolder pvhY = PropertyValuesHolder.ofFloat("y", 100f); |
| 900 | ObjectAnimator.ofPropertyValuesHolder(myView, pvhX, pvyY).start(); |
| 901 | </pre> |
| 902 | |
| 903 | <p><strong>ViewPropertyAnimator</strong></p> |
| 904 | <pre> |
| 905 | myView.animate().x(50f).y(100f); |
| 906 | </pre> |
| 907 | |
| 908 | <p> |
| 909 | For more detailed information about {@link |
| 910 | android.view.ViewPropertyAnimator}, see the corresponding Android Developers |
| 911 | <a href="http://android-developers.blogspot.com/2011/05/introducing-viewpropertyanimator.html">blog |
| 912 | post</a>.</p> |
| 913 | |
| 914 | <h2 id="declaring-xml">Declaring Animations in XML</h2> |
| 915 | |
| 916 | <p>The property animation system lets you declare property animations with XML instead of doing |
| 917 | it programmatically. By defining your animations in XML, you can easily reuse your animations |
| 918 | in multiple activities and more easily edit the animation sequence.</p> |
| 919 | |
| 920 | <p>To distinguish animation files that use the new property animation APIs from those that use the |
| 921 | legacy <a href="{@docRoot}guide/topics/graphics/view-animation.html">view animation</a> framework, |
| 922 | starting with Android 3.1, you should save the XML files for property animations in the {@code |
| 923 | res/animator/} directory (instead of {@code res/anim/}). Using the {@code animator} directory name |
| 924 | is optional, but necessary if you want to use the layout editor tools in the Eclipse ADT plugin (ADT |
| 925 | 11.0.0+), because ADT only searches the {@code res/animator/} directory for property animation |
| 926 | resources.</p> |
| 927 | |
| 928 | <p>The following property animation classes have XML declaration support with the |
| 929 | following XML tags:</p> |
| 930 | |
| 931 | <ul> |
| 932 | <li>{@link android.animation.ValueAnimator} - <code><animator></code></li> |
| 933 | |
| 934 | <li>{@link android.animation.ObjectAnimator} - <code><objectAnimator></code></li> |
| 935 | |
| 936 | <li>{@link android.animation.AnimatorSet} - <code><set></code></li> |
| 937 | </ul> |
| 938 | |
| 939 | <p>The following example plays the two sets of object animations sequentially, with the first nested |
| 940 | set playing two object animations together:</p> |
| 941 | |
| 942 | <pre> |
| 943 | <set android:ordering="sequentially"> |
| 944 | <set> |
| 945 | <objectAnimator |
| 946 | android:propertyName="x" |
| 947 | android:duration="500" |
| 948 | android:valueTo="400" |
| 949 | android:valueType="intType"/> |
| 950 | <objectAnimator |
| 951 | android:propertyName="y" |
| 952 | android:duration="500" |
| 953 | android:valueTo="300" |
| 954 | android:valueType="intType"/> |
| 955 | </set> |
| 956 | <objectAnimator |
| 957 | android:propertyName="alpha" |
| 958 | android:duration="500" |
| 959 | android:valueTo="1f"/> |
| 960 | </set> |
| 961 | </pre> |
| 962 | <p>In order to run this animation, you must inflate the XML resources in your code to an {@link |
| 963 | android.animation.AnimatorSet} object, and then set the target objects for all of the animations |
| 964 | before starting the animation set. Calling {@link android.animation.AnimatorSet#setTarget |
| 965 | setTarget()} sets a single target object for all children of the {@link |
| 966 | android.animation.AnimatorSet} as a convenience. The following code shows how to do this:</p> |
| 967 | |
| 968 | <pre> |
| 969 | AnimatorSet set = (AnimatorSet) AnimatorInflater.loadAnimator(myContext, |
| 970 | R.anim.property_animator); |
| 971 | set.setTarget(myObject); |
| 972 | set.start(); |
| 973 | </pre> |
| 974 | |
| 975 | <p>For information about the XML syntax for defining property animations, see <a |
| 976 | href="{@docRoot}guide/topics/resources/animation-resource.html#Property">Animation Resources</a>. |
| 977 | |