ObjectAnimator.java revision 1ffb280a7d2c70cc16d709c685f5d31fdb86b5e4
1/* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package android.animation; 18 19import android.util.Log; 20import android.util.Property; 21 22import java.util.ArrayList; 23 24/** 25 * This subclass of {@link ValueAnimator} provides support for animating properties on target objects. 26 * The constructors of this class take parameters to define the target object that will be animated 27 * as well as the name of the property that will be animated. Appropriate set/get functions 28 * are then determined internally and the animation will call these functions as necessary to 29 * animate the property. 30 * 31 * <div class="special reference"> 32 * <h3>Developer Guides</h3> 33 * <p>For more information about animating with {@code ObjectAnimator}, read the 34 * <a href="{@docRoot}guide/topics/graphics/prop-animation.html#object-animator">Property 35 * Animation</a> developer guide.</p> 36 * </div> 37 * 38 * @see #setPropertyName(String) 39 * 40 */ 41public final class ObjectAnimator extends ValueAnimator { 42 private static final boolean DBG = false; 43 44 // The target object on which the property exists, set in the constructor 45 private Object mTarget; 46 47 private String mPropertyName; 48 49 private Property mProperty; 50 51 private boolean mAutoCancel = false; 52 53 /** 54 * Sets the name of the property that will be animated. This name is used to derive 55 * a setter function that will be called to set animated values. 56 * For example, a property name of <code>foo</code> will result 57 * in a call to the function <code>setFoo()</code> on the target object. If either 58 * <code>valueFrom</code> or <code>valueTo</code> is null, then a getter function will 59 * also be derived and called. 60 * 61 * <p>For best performance of the mechanism that calls the setter function determined by the 62 * name of the property being animated, use <code>float</code> or <code>int</code> typed values, 63 * and make the setter function for those properties have a <code>void</code> return value. This 64 * will cause the code to take an optimized path for these constrained circumstances. Other 65 * property types and return types will work, but will have more overhead in processing 66 * the requests due to normal reflection mechanisms.</p> 67 * 68 * <p>Note that the setter function derived from this property name 69 * must take the same parameter type as the 70 * <code>valueFrom</code> and <code>valueTo</code> properties, otherwise the call to 71 * the setter function will fail.</p> 72 * 73 * <p>If this ObjectAnimator has been set up to animate several properties together, 74 * using more than one PropertyValuesHolder objects, then setting the propertyName simply 75 * sets the propertyName in the first of those PropertyValuesHolder objects.</p> 76 * 77 * @param propertyName The name of the property being animated. Should not be null. 78 */ 79 public void setPropertyName(String propertyName) { 80 // mValues could be null if this is being constructed piecemeal. Just record the 81 // propertyName to be used later when setValues() is called if so. 82 if (mValues != null) { 83 PropertyValuesHolder valuesHolder = mValues[0]; 84 String oldName = valuesHolder.getPropertyName(); 85 valuesHolder.setPropertyName(propertyName); 86 mValuesMap.remove(oldName); 87 mValuesMap.put(propertyName, valuesHolder); 88 } 89 mPropertyName = propertyName; 90 // New property/values/target should cause re-initialization prior to starting 91 mInitialized = false; 92 } 93 94 /** 95 * Sets the property that will be animated. Property objects will take precedence over 96 * properties specified by the {@link #setPropertyName(String)} method. Animations should 97 * be set up to use one or the other, not both. 98 * 99 * @param property The property being animated. Should not be null. 100 */ 101 public void setProperty(Property property) { 102 // mValues could be null if this is being constructed piecemeal. Just record the 103 // propertyName to be used later when setValues() is called if so. 104 if (mValues != null) { 105 PropertyValuesHolder valuesHolder = mValues[0]; 106 String oldName = valuesHolder.getPropertyName(); 107 valuesHolder.setProperty(property); 108 mValuesMap.remove(oldName); 109 mValuesMap.put(mPropertyName, valuesHolder); 110 } 111 if (mProperty != null) { 112 mPropertyName = property.getName(); 113 } 114 mProperty = property; 115 // New property/values/target should cause re-initialization prior to starting 116 mInitialized = false; 117 } 118 119 /** 120 * Gets the name of the property that will be animated. This name will be used to derive 121 * a setter function that will be called to set animated values. 122 * For example, a property name of <code>foo</code> will result 123 * in a call to the function <code>setFoo()</code> on the target object. If either 124 * <code>valueFrom</code> or <code>valueTo</code> is null, then a getter function will 125 * also be derived and called. 126 * 127 * <p>If this animator was created with a {@link Property} object instead of the 128 * string name of a property, then this method will return the {@link 129 * Property#getName() name} of that Property object instead. If this animator was 130 * created with one or more {@link PropertyValuesHolder} objects, then this method 131 * will return the {@link PropertyValuesHolder#getPropertyName() name} of that 132 * object (if there was just one) or a comma-separated list of all of the 133 * names (if there are more than one).</p> 134 */ 135 public String getPropertyName() { 136 String propertyName = null; 137 if (mPropertyName != null) { 138 propertyName = mPropertyName; 139 } else if (mProperty != null) { 140 propertyName = mProperty.getName(); 141 } else if (mValues != null && mValues.length > 0) { 142 for (int i = 0; i < mValues.length; ++i) { 143 if (i == 0) { 144 propertyName = ""; 145 } else { 146 propertyName += ","; 147 } 148 propertyName += mValues[i].getPropertyName(); 149 } 150 } 151 return propertyName; 152 } 153 154 @Override 155 String getNameForTrace() { 156 return "animator:" + getPropertyName(); 157 } 158 159 /** 160 * Creates a new ObjectAnimator object. This default constructor is primarily for 161 * use internally; the other constructors which take parameters are more generally 162 * useful. 163 */ 164 public ObjectAnimator() { 165 } 166 167 /** 168 * Private utility constructor that initializes the target object and name of the 169 * property being animated. 170 * 171 * @param target The object whose property is to be animated. This object should 172 * have a public method on it called <code>setName()</code>, where <code>name</code> is 173 * the value of the <code>propertyName</code> parameter. 174 * @param propertyName The name of the property being animated. 175 */ 176 private ObjectAnimator(Object target, String propertyName) { 177 mTarget = target; 178 setPropertyName(propertyName); 179 } 180 181 /** 182 * Private utility constructor that initializes the target object and property being animated. 183 * 184 * @param target The object whose property is to be animated. 185 * @param property The property being animated. 186 */ 187 private <T> ObjectAnimator(T target, Property<T, ?> property) { 188 mTarget = target; 189 setProperty(property); 190 } 191 192 /** 193 * Constructs and returns an ObjectAnimator that animates between int values. A single 194 * value implies that that value is the one being animated to. Two values imply starting 195 * and ending values. More than two values imply a starting value, values to animate through 196 * along the way, and an ending value (these values will be distributed evenly across 197 * the duration of the animation). 198 * 199 * @param target The object whose property is to be animated. This object should 200 * have a public method on it called <code>setName()</code>, where <code>name</code> is 201 * the value of the <code>propertyName</code> parameter. 202 * @param propertyName The name of the property being animated. 203 * @param values A set of values that the animation will animate between over time. 204 * @return An ObjectAnimator object that is set up to animate between the given values. 205 */ 206 public static ObjectAnimator ofInt(Object target, String propertyName, int... values) { 207 ObjectAnimator anim = new ObjectAnimator(target, propertyName); 208 anim.setIntValues(values); 209 return anim; 210 } 211 212 /** 213 * Constructs and returns an ObjectAnimator that animates between int values. A single 214 * value implies that that value is the one being animated to. Two values imply starting 215 * and ending values. More than two values imply a starting value, values to animate through 216 * along the way, and an ending value (these values will be distributed evenly across 217 * the duration of the animation). 218 * 219 * @param target The object whose property is to be animated. 220 * @param property The property being animated. 221 * @param values A set of values that the animation will animate between over time. 222 * @return An ObjectAnimator object that is set up to animate between the given values. 223 */ 224 public static <T> ObjectAnimator ofInt(T target, Property<T, Integer> property, int... values) { 225 ObjectAnimator anim = new ObjectAnimator(target, property); 226 anim.setIntValues(values); 227 return anim; 228 } 229 230 /** 231 * Constructs and returns an ObjectAnimator that animates over int values for a multiple 232 * parameters setter. Only public methods that take only int parameters are supported. 233 * Each <code>int[]</code> contains a complete set of parameters to the setter method. 234 * At least two <code>int[]</code> values must be provided, a start and end. More than two 235 * values imply a starting value, values to animate through along the way, and an ending 236 * value (these values will be distributed evenly across the duration of the animation). 237 * 238 * @param target The object whose property is to be animated. This object may 239 * have a public method on it called <code>setName()</code>, where <code>name</code> is 240 * the value of the <code>propertyName</code> parameter. <code>propertyName</code> may also 241 * be the case-sensitive complete name of the public setter method. 242 * @param propertyName The name of the property being animated or the name of the setter method. 243 * @param values A set of values that the animation will animate between over time. 244 * @return An ObjectAnimator object that is set up to animate between the given values. 245 */ 246 public static ObjectAnimator ofMultiInt(Object target, String propertyName, int[][] values) { 247 PropertyValuesHolder pvh = PropertyValuesHolder.ofMultiInt(propertyName, values); 248 return ofPropertyValuesHolder(target, pvh); 249 } 250 251 /** 252 * Constructs and returns an ObjectAnimator that animates over values for a multiple int 253 * parameters setter. Only public methods that take only int parameters are supported. 254 * <p>At least two values must be provided, a start and end. More than two 255 * values imply a starting value, values to animate through along the way, and an ending 256 * value (these values will be distributed evenly across the duration of the animation).</p> 257 * 258 * @param target The object whose property is to be animated. This object may 259 * have a public method on it called <code>setName()</code>, where <code>name</code> is 260 * the value of the <code>propertyName</code> parameter. <code>propertyName</code> may also 261 * be the complete name of the public method. 262 * @param propertyName The name of the property being animated or the name of the setter method. 263 * @param converter Converts T objects into int parameters for the multi-value setter. 264 * @param evaluator A TypeEvaluator that will be called on each animation frame to 265 * provide the necessary interpolation between the Object values to derive the animated 266 * value. 267 * @param values A set of values that the animation will animate between over time. 268 * @return An ObjectAnimator object that is set up to animate between the given values. 269 */ 270 public static <T> ObjectAnimator ofMultiInt(Object target, String propertyName, 271 TypeConverter<T, int[]> converter, TypeEvaluator<T> evaluator, T... values) { 272 PropertyValuesHolder pvh = PropertyValuesHolder.ofMultiInt(propertyName, converter, 273 evaluator, values); 274 return ObjectAnimator.ofPropertyValuesHolder(target, pvh); 275 } 276 277 /** 278 * Constructs and returns an ObjectAnimator that animates between color values. A single 279 * value implies that that value is the one being animated to. Two values imply starting 280 * and ending values. More than two values imply a starting value, values to animate through 281 * along the way, and an ending value (these values will be distributed evenly across 282 * the duration of the animation). 283 * 284 * @param target The object whose property is to be animated. This object should 285 * have a public method on it called <code>setName()</code>, where <code>name</code> is 286 * the value of the <code>propertyName</code> parameter. 287 * @param propertyName The name of the property being animated. 288 * @param values A set of values that the animation will animate between over time. 289 * @return An ObjectAnimator object that is set up to animate between the given values. 290 */ 291 public static ObjectAnimator ofArgb(Object target, String propertyName, int... values) { 292 ObjectAnimator animator = ofInt(target, propertyName, values); 293 animator.setEvaluator(ArgbEvaluator.getInstance()); 294 return animator; 295 } 296 297 /** 298 * Constructs and returns an ObjectAnimator that animates between color values. A single 299 * value implies that that value is the one being animated to. Two values imply starting 300 * and ending values. More than two values imply a starting value, values to animate through 301 * along the way, and an ending value (these values will be distributed evenly across 302 * the duration of the animation). 303 * 304 * @param target The object whose property is to be animated. 305 * @param property The property being animated. 306 * @param values A set of values that the animation will animate between over time. 307 * @return An ObjectAnimator object that is set up to animate between the given values. 308 */ 309 public static <T> ObjectAnimator ofArgb(T target, Property<T, Integer> property, 310 int... values) { 311 ObjectAnimator animator = ofInt(target, property, values); 312 animator.setEvaluator(ArgbEvaluator.getInstance()); 313 return animator; 314 } 315 316 /** 317 * Constructs and returns an ObjectAnimator that animates between float values. A single 318 * value implies that that value is the one being animated to. Two values imply starting 319 * and ending values. More than two values imply a starting value, values to animate through 320 * along the way, and an ending value (these values will be distributed evenly across 321 * the duration of the animation). 322 * 323 * @param target The object whose property is to be animated. This object should 324 * have a public method on it called <code>setName()</code>, where <code>name</code> is 325 * the value of the <code>propertyName</code> parameter. 326 * @param propertyName The name of the property being animated. 327 * @param values A set of values that the animation will animate between over time. 328 * @return An ObjectAnimator object that is set up to animate between the given values. 329 */ 330 public static ObjectAnimator ofFloat(Object target, String propertyName, float... values) { 331 ObjectAnimator anim = new ObjectAnimator(target, propertyName); 332 anim.setFloatValues(values); 333 return anim; 334 } 335 336 /** 337 * Constructs and returns an ObjectAnimator that animates between float values. A single 338 * value implies that that value is the one being animated to. Two values imply starting 339 * and ending values. More than two values imply a starting value, values to animate through 340 * along the way, and an ending value (these values will be distributed evenly across 341 * the duration of the animation). 342 * 343 * @param target The object whose property is to be animated. 344 * @param property The property being animated. 345 * @param values A set of values that the animation will animate between over time. 346 * @return An ObjectAnimator object that is set up to animate between the given values. 347 */ 348 public static <T> ObjectAnimator ofFloat(T target, Property<T, Float> property, 349 float... values) { 350 ObjectAnimator anim = new ObjectAnimator(target, property); 351 anim.setFloatValues(values); 352 return anim; 353 } 354 355 /** 356 * Constructs and returns an ObjectAnimator that animates over float values for a multiple 357 * parameters setter. Only public methods that take only float parameters are supported. 358 * Each <code>float[]</code> contains a complete set of parameters to the setter method. 359 * At least two <code>float[]</code> values must be provided, a start and end. More than two 360 * values imply a starting value, values to animate through along the way, and an ending 361 * value (these values will be distributed evenly across the duration of the animation). 362 * 363 * @param target The object whose property is to be animated. This object may 364 * have a public method on it called <code>setName()</code>, where <code>name</code> is 365 * the value of the <code>propertyName</code> parameter. <code>propertyName</code> may also 366 * be the complete name of the public method. 367 * @param propertyName The name of the property being animated or the name of the setter method. 368 * @param values A set of values that the animation will animate between over time. 369 * @return An ObjectAnimator object that is set up to animate between the given values. 370 */ 371 public static ObjectAnimator ofMultiFloat(Object target, String propertyName, 372 float[][] values) { 373 PropertyValuesHolder pvh = PropertyValuesHolder.ofMultiFloat(propertyName, values); 374 return ofPropertyValuesHolder(target, pvh); 375 } 376 377 /** 378 * Constructs and returns an ObjectAnimator that animates over values for a multiple float 379 * parameters setter. Only public methods that take only float parameters are supported. 380 * <p>At least two values must be provided, a start and end. More than two 381 * values imply a starting value, values to animate through along the way, and an ending 382 * value (these values will be distributed evenly across the duration of the animation).</p> 383 * 384 * @param target The object whose property is to be animated. This object may 385 * have a public method on it called <code>setName()</code>, where <code>name</code> is 386 * the value of the <code>propertyName</code> parameter. <code>propertyName</code> may also 387 * be the case-sensitive complete name of the public setter method. 388 * @param propertyName The name of the property being animated or the name of the setter method. 389 * @param converter Converts T objects into float parameters for the multi-value setter. 390 * @param evaluator A TypeEvaluator that will be called on each animation frame to 391 * provide the necessary interpolation between the Object values to derive the animated 392 * value. 393 * @param values A set of values that the animation will animate between over time. 394 * @return An ObjectAnimator object that is set up to animate between the given values. 395 */ 396 public static <T> ObjectAnimator ofMultiFloat(Object target, String propertyName, 397 TypeConverter<T, float[]> converter, TypeEvaluator<T> evaluator, T... values) { 398 PropertyValuesHolder pvh = PropertyValuesHolder.ofMultiFloat(propertyName, converter, 399 evaluator, values); 400 return ObjectAnimator.ofPropertyValuesHolder(target, pvh); 401 } 402 403 /** 404 * Constructs and returns an ObjectAnimator that animates between Object values. A single 405 * value implies that that value is the one being animated to. Two values imply starting 406 * and ending values. More than two values imply a starting value, values to animate through 407 * along the way, and an ending value (these values will be distributed evenly across 408 * the duration of the animation). 409 * 410 * @param target The object whose property is to be animated. This object should 411 * have a public method on it called <code>setName()</code>, where <code>name</code> is 412 * the value of the <code>propertyName</code> parameter. 413 * @param propertyName The name of the property being animated. 414 * @param evaluator A TypeEvaluator that will be called on each animation frame to 415 * provide the necessary interpolation between the Object values to derive the animated 416 * value. 417 * @param values A set of values that the animation will animate between over time. 418 * @return An ObjectAnimator object that is set up to animate between the given values. 419 */ 420 public static ObjectAnimator ofObject(Object target, String propertyName, 421 TypeEvaluator evaluator, Object... values) { 422 ObjectAnimator anim = new ObjectAnimator(target, propertyName); 423 anim.setObjectValues(values); 424 anim.setEvaluator(evaluator); 425 return anim; 426 } 427 428 /** 429 * Constructs and returns an ObjectAnimator that animates between Object values. A single 430 * value implies that that value is the one being animated to. Two values imply starting 431 * and ending values. More than two values imply a starting value, values to animate through 432 * along the way, and an ending value (these values will be distributed evenly across 433 * the duration of the animation). 434 * 435 * @param target The object whose property is to be animated. 436 * @param property The property being animated. 437 * @param evaluator A TypeEvaluator that will be called on each animation frame to 438 * provide the necessary interpolation between the Object values to derive the animated 439 * value. 440 * @param values A set of values that the animation will animate between over time. 441 * @return An ObjectAnimator object that is set up to animate between the given values. 442 */ 443 public static <T, V> ObjectAnimator ofObject(T target, Property<T, V> property, 444 TypeEvaluator<V> evaluator, V... values) { 445 ObjectAnimator anim = new ObjectAnimator(target, property); 446 anim.setObjectValues(values); 447 anim.setEvaluator(evaluator); 448 return anim; 449 } 450 451 /** 452 * Constructs and returns an ObjectAnimator that animates between Object values. A single 453 * value implies that that value is the one being animated to. Two values imply starting 454 * and ending values. More than two values imply a starting value, values to animate through 455 * along the way, and an ending value (these values will be distributed evenly across 456 * the duration of the animation). This variant supplies a <code>TypeConverter</code> to 457 * convert from the animated values to the type of the property. If only one value is 458 * supplied, the <code>TypeConverter</code> must implement 459 * {@link TypeConverter#convertBack(Object)} to retrieve the current value. 460 * 461 * @param target The object whose property is to be animated. 462 * @param property The property being animated. 463 * @param converter Converts the animated object to the Property type. 464 * @param evaluator A TypeEvaluator that will be called on each animation frame to 465 * provide the necessary interpolation between the Object values to derive the animated 466 * value. 467 * @param values A set of values that the animation will animate between over time. 468 * @return An ObjectAnimator object that is set up to animate between the given values. 469 */ 470 public static <T, V, P> ObjectAnimator ofObject(T target, Property<T, P> property, 471 TypeConverter<V, P> converter, TypeEvaluator<V> evaluator, V... values) { 472 PropertyValuesHolder pvh = PropertyValuesHolder.ofObject(property, converter, evaluator, 473 values); 474 return ofPropertyValuesHolder(target, pvh); 475 } 476 477 /** 478 * Constructs and returns an ObjectAnimator that animates between the sets of values specified 479 * in <code>PropertyValueHolder</code> objects. This variant should be used when animating 480 * several properties at once with the same ObjectAnimator, since PropertyValuesHolder allows 481 * you to associate a set of animation values with a property name. 482 * 483 * @param target The object whose property is to be animated. Depending on how the 484 * PropertyValuesObjects were constructed, the target object should either have the {@link 485 * android.util.Property} objects used to construct the PropertyValuesHolder objects or (if the 486 * PropertyValuesHOlder objects were created with property names) the target object should have 487 * public methods on it called <code>setName()</code>, where <code>name</code> is the name of 488 * the property passed in as the <code>propertyName</code> parameter for each of the 489 * PropertyValuesHolder objects. 490 * @param values A set of PropertyValuesHolder objects whose values will be animated between 491 * over time. 492 * @return An ObjectAnimator object that is set up to animate between the given values. 493 */ 494 public static ObjectAnimator ofPropertyValuesHolder(Object target, 495 PropertyValuesHolder... values) { 496 ObjectAnimator anim = new ObjectAnimator(); 497 anim.mTarget = target; 498 anim.setValues(values); 499 return anim; 500 } 501 502 @Override 503 public void setIntValues(int... values) { 504 if (mValues == null || mValues.length == 0) { 505 // No values yet - this animator is being constructed piecemeal. Init the values with 506 // whatever the current propertyName is 507 if (mProperty != null) { 508 setValues(PropertyValuesHolder.ofInt(mProperty, values)); 509 } else { 510 setValues(PropertyValuesHolder.ofInt(mPropertyName, values)); 511 } 512 } else { 513 super.setIntValues(values); 514 } 515 } 516 517 @Override 518 public void setFloatValues(float... values) { 519 if (mValues == null || mValues.length == 0) { 520 // No values yet - this animator is being constructed piecemeal. Init the values with 521 // whatever the current propertyName is 522 if (mProperty != null) { 523 setValues(PropertyValuesHolder.ofFloat(mProperty, values)); 524 } else { 525 setValues(PropertyValuesHolder.ofFloat(mPropertyName, values)); 526 } 527 } else { 528 super.setFloatValues(values); 529 } 530 } 531 532 @Override 533 public void setObjectValues(Object... values) { 534 if (mValues == null || mValues.length == 0) { 535 // No values yet - this animator is being constructed piecemeal. Init the values with 536 // whatever the current propertyName is 537 if (mProperty != null) { 538 setValues(PropertyValuesHolder.ofObject(mProperty, (TypeEvaluator) null, values)); 539 } else { 540 setValues(PropertyValuesHolder.ofObject(mPropertyName, 541 (TypeEvaluator) null, values)); 542 } 543 } else { 544 super.setObjectValues(values); 545 } 546 } 547 548 /** 549 * autoCancel controls whether an ObjectAnimator will be canceled automatically 550 * when any other ObjectAnimator with the same target and properties is started. 551 * Setting this flag may make it easier to run different animators on the same target 552 * object without having to keep track of whether there are conflicting animators that 553 * need to be manually canceled. Canceling animators must have the same exact set of 554 * target properties, in the same order. 555 * 556 * @param cancel Whether future ObjectAnimators with the same target and properties 557 * as this ObjectAnimator will cause this ObjectAnimator to be canceled. 558 */ 559 public void setAutoCancel(boolean cancel) { 560 mAutoCancel = cancel; 561 } 562 563 private boolean hasSameTargetAndProperties(Animator anim) { 564 if (anim instanceof ObjectAnimator) { 565 PropertyValuesHolder[] theirValues = ((ObjectAnimator) anim).getValues(); 566 if (((ObjectAnimator) anim).getTarget() == mTarget && 567 mValues.length == theirValues.length) { 568 for (int i = 0; i < mValues.length; ++i) { 569 PropertyValuesHolder pvhMine = mValues[i]; 570 PropertyValuesHolder pvhTheirs = theirValues[i]; 571 if (pvhMine.getPropertyName() == null || 572 !pvhMine.getPropertyName().equals(pvhTheirs.getPropertyName())) { 573 return false; 574 } 575 } 576 return true; 577 } 578 } 579 return false; 580 } 581 582 @Override 583 public void start() { 584 // See if any of the current active/pending animators need to be canceled 585 AnimationHandler handler = sAnimationHandler.get(); 586 if (handler != null) { 587 int numAnims = handler.mAnimations.size(); 588 for (int i = numAnims - 1; i >= 0; i--) { 589 if (handler.mAnimations.get(i) instanceof ObjectAnimator) { 590 ObjectAnimator anim = (ObjectAnimator) handler.mAnimations.get(i); 591 if (anim.mAutoCancel && hasSameTargetAndProperties(anim)) { 592 anim.cancel(); 593 } 594 } 595 } 596 numAnims = handler.mPendingAnimations.size(); 597 for (int i = numAnims - 1; i >= 0; i--) { 598 if (handler.mPendingAnimations.get(i) instanceof ObjectAnimator) { 599 ObjectAnimator anim = (ObjectAnimator) handler.mPendingAnimations.get(i); 600 if (anim.mAutoCancel && hasSameTargetAndProperties(anim)) { 601 anim.cancel(); 602 } 603 } 604 } 605 numAnims = handler.mDelayedAnims.size(); 606 for (int i = numAnims - 1; i >= 0; i--) { 607 if (handler.mDelayedAnims.get(i) instanceof ObjectAnimator) { 608 ObjectAnimator anim = (ObjectAnimator) handler.mDelayedAnims.get(i); 609 if (anim.mAutoCancel && hasSameTargetAndProperties(anim)) { 610 anim.cancel(); 611 } 612 } 613 } 614 } 615 if (DBG) { 616 Log.d("ObjectAnimator", "Anim target, duration: " + mTarget + ", " + getDuration()); 617 for (int i = 0; i < mValues.length; ++i) { 618 PropertyValuesHolder pvh = mValues[i]; 619 ArrayList<Keyframe> keyframes = pvh.mKeyframeSet.mKeyframes; 620 Log.d("ObjectAnimator", " Values[" + i + "]: " + 621 pvh.getPropertyName() + ", " + keyframes.get(0).getValue() + ", " + 622 keyframes.get(pvh.mKeyframeSet.mNumKeyframes - 1).getValue()); 623 } 624 } 625 super.start(); 626 } 627 628 /** 629 * This function is called immediately before processing the first animation 630 * frame of an animation. If there is a nonzero <code>startDelay</code>, the 631 * function is called after that delay ends. 632 * It takes care of the final initialization steps for the 633 * animation. This includes setting mEvaluator, if the user has not yet 634 * set it up, and the setter/getter methods, if the user did not supply 635 * them. 636 * 637 * <p>Overriders of this method should call the superclass method to cause 638 * internal mechanisms to be set up correctly.</p> 639 */ 640 @Override 641 void initAnimation() { 642 if (!mInitialized) { 643 // mValueType may change due to setter/getter setup; do this before calling super.init(), 644 // which uses mValueType to set up the default type evaluator. 645 int numValues = mValues.length; 646 for (int i = 0; i < numValues; ++i) { 647 mValues[i].setupSetterAndGetter(mTarget); 648 } 649 super.initAnimation(); 650 } 651 } 652 653 /** 654 * Sets the length of the animation. The default duration is 300 milliseconds. 655 * 656 * @param duration The length of the animation, in milliseconds. 657 * @return ObjectAnimator The object called with setDuration(). This return 658 * value makes it easier to compose statements together that construct and then set the 659 * duration, as in 660 * <code>ObjectAnimator.ofInt(target, propertyName, 0, 10).setDuration(500).start()</code>. 661 */ 662 @Override 663 public ObjectAnimator setDuration(long duration) { 664 super.setDuration(duration); 665 return this; 666 } 667 668 669 /** 670 * The target object whose property will be animated by this animation 671 * 672 * @return The object being animated 673 */ 674 public Object getTarget() { 675 return mTarget; 676 } 677 678 /** 679 * Sets the target object whose property will be animated by this animation 680 * 681 * @param target The object being animated 682 */ 683 @Override 684 public void setTarget(Object target) { 685 if (mTarget != target) { 686 final Object oldTarget = mTarget; 687 mTarget = target; 688 if (oldTarget != null && target != null && oldTarget.getClass() == target.getClass()) { 689 return; 690 } 691 // New target type should cause re-initialization prior to starting 692 mInitialized = false; 693 } 694 } 695 696 @Override 697 public void setupStartValues() { 698 initAnimation(); 699 int numValues = mValues.length; 700 for (int i = 0; i < numValues; ++i) { 701 mValues[i].setupStartValue(mTarget); 702 } 703 } 704 705 @Override 706 public void setupEndValues() { 707 initAnimation(); 708 int numValues = mValues.length; 709 for (int i = 0; i < numValues; ++i) { 710 mValues[i].setupEndValue(mTarget); 711 } 712 } 713 714 /** 715 * This method is called with the elapsed fraction of the animation during every 716 * animation frame. This function turns the elapsed fraction into an interpolated fraction 717 * and then into an animated value (from the evaluator. The function is called mostly during 718 * animation updates, but it is also called when the <code>end()</code> 719 * function is called, to set the final value on the property. 720 * 721 * <p>Overrides of this method must call the superclass to perform the calculation 722 * of the animated value.</p> 723 * 724 * @param fraction The elapsed fraction of the animation. 725 */ 726 @Override 727 void animateValue(float fraction) { 728 super.animateValue(fraction); 729 int numValues = mValues.length; 730 for (int i = 0; i < numValues; ++i) { 731 mValues[i].setAnimatedValue(mTarget); 732 } 733 } 734 735 @Override 736 public ObjectAnimator clone() { 737 final ObjectAnimator anim = (ObjectAnimator) super.clone(); 738 return anim; 739 } 740 741 @Override 742 public String toString() { 743 String returnVal = "ObjectAnimator@" + Integer.toHexString(hashCode()) + ", target " + 744 mTarget; 745 if (mValues != null) { 746 for (int i = 0; i < mValues.length; ++i) { 747 returnVal += "\n " + mValues[i].toString(); 748 } 749 } 750 return returnVal; 751 } 752} 753