From fa21bdfd5a8a5da3ec0530f7cc884994f92dc597 Mon Sep 17 00:00:00 2001 From: Chet Haase Date: Thu, 21 Apr 2016 17:41:54 -0700 Subject: [PATCH] Document behavior of object references in Animator classes Animators that are created with Object values may have undefined behavior when those objects are changed outside of the animator itself. For example, an animator created with a start Rect and end Rect will animate the bounds between those two objects. But if the caller changes either the start or end rect before or during the animation, that will affect the values used on every frame of the animation. Issue #28304520 Strange interpolation of property values holder values Change-Id: Id6ac19c8369ae34450e6b53d68f5e492b27c577e --- .../android/animation/ObjectAnimator.java | 15 +++++++++++++ .../animation/PropertyValuesHolder.java | 22 ++++++++++++++++++- .../java/android/animation/ValueAnimator.java | 10 +++++++++ 3 files changed, 46 insertions(+), 1 deletion(-) diff --git a/core/java/android/animation/ObjectAnimator.java b/core/java/android/animation/ObjectAnimator.java index 542ecf41756ec..1d1086049fddd 100644 --- a/core/java/android/animation/ObjectAnimator.java +++ b/core/java/android/animation/ObjectAnimator.java @@ -585,6 +585,11 @@ public final class ObjectAnimator extends ValueAnimator { * along the way, and an ending value (these values will be distributed evenly across * the duration of the animation). * + *

Note: The values are stored as references to the original + * objects, which means that changes to those objects after this method is called will + * affect the values on the animator. If the objects will be mutated externally after + * this method is called, callers should pass a copy of those objects instead. + * * @param target The object whose property is to be animated. This object should * have a public method on it called setName(), where name is * the value of the propertyName parameter. @@ -635,6 +640,11 @@ public final class ObjectAnimator extends ValueAnimator { * along the way, and an ending value (these values will be distributed evenly across * the duration of the animation). * + *

Note: The values are stored as references to the original + * objects, which means that changes to those objects after this method is called will + * affect the values on the animator. If the objects will be mutated externally after + * this method is called, callers should pass a copy of those objects instead. + * * @param target The object whose property is to be animated. * @param property The property being animated. * @param evaluator A TypeEvaluator that will be called on each animation frame to @@ -663,6 +673,11 @@ public final class ObjectAnimator extends ValueAnimator { * supplied, the TypeConverter must be a * {@link android.animation.BidirectionalTypeConverter} to retrieve the current value. * + *

Note: The values are stored as references to the original + * objects, which means that changes to those objects after this method is called will + * affect the values on the animator. If the objects will be mutated externally after + * this method is called, callers should pass a copy of those objects instead. + * * @param target The object whose property is to be animated. * @param property The property being animated. * @param converter Converts the animated object to the Property type. diff --git a/core/java/android/animation/PropertyValuesHolder.java b/core/java/android/animation/PropertyValuesHolder.java index ffea6f5e0003b..224823ee2ff11 100644 --- a/core/java/android/animation/PropertyValuesHolder.java +++ b/core/java/android/animation/PropertyValuesHolder.java @@ -388,6 +388,11 @@ public class PropertyValuesHolder implements Cloneable { * set of Object values. This variant also takes a TypeEvaluator because the system * cannot automatically interpolate between objects of unknown type. * + *

Note: The Object values are stored as references to the original + * objects, which means that changes to those objects after this method is called will + * affect the values on the PropertyValuesHolder. If the objects will be mutated externally + * after this method is called, callers should pass a copy of those objects instead. + * * @param propertyName The name of the property being animated. * @param evaluator A TypeEvaluator that will be called on each animation frame to * provide the necessary interpolation between the Object values to derive the animated @@ -433,6 +438,11 @@ public class PropertyValuesHolder implements Cloneable { * set of Object values. This variant also takes a TypeEvaluator because the system * cannot automatically interpolate between objects of unknown type. * + *

Note: The Object values are stored as references to the original + * objects, which means that changes to those objects after this method is called will + * affect the values on the PropertyValuesHolder. If the objects will be mutated externally + * after this method is called, callers should pass a copy of those objects instead. + * * @param property The property being animated. Should not be null. * @param evaluator A TypeEvaluator that will be called on each animation frame to * provide the necessary interpolation between the Object values to derive the animated @@ -458,6 +468,11 @@ public class PropertyValuesHolder implements Cloneable { * must be a {@link android.animation.BidirectionalTypeConverter} to retrieve the current * value. * + *

Note: The Object values are stored as references to the original + * objects, which means that changes to those objects after this method is called will + * affect the values on the PropertyValuesHolder. If the objects will be mutated externally + * after this method is called, callers should pass a copy of those objects instead. + * * @param property The property being animated. Should not be null. * @param converter Converts the animated object to the Property type. * @param evaluator A TypeEvaluator that will be called on each animation frame to @@ -636,7 +651,12 @@ public class PropertyValuesHolder implements Cloneable { * {@link ObjectAnimator}, and with a getter function * derived automatically from propertyName, since otherwise PropertyValuesHolder has * no way of determining what the value should be. - * + * + *

Note: The Object values are stored as references to the original + * objects, which means that changes to those objects after this method is called will + * affect the values on the PropertyValuesHolder. If the objects will be mutated externally + * after this method is called, callers should pass a copy of those objects instead. + * * @param values One or more values that the animation will animate between. */ public void setObjectValues(Object... values) { diff --git a/core/java/android/animation/ValueAnimator.java b/core/java/android/animation/ValueAnimator.java index 31035a746d5f8..0a9b5ded89247 100644 --- a/core/java/android/animation/ValueAnimator.java +++ b/core/java/android/animation/ValueAnimator.java @@ -353,6 +353,11 @@ public class ValueAnimator extends Animator implements AnimationHandler.Animatio * from the target object and property being animated). Therefore, there should typically * be two or more values. * + *

Note: The Object values are stored as references to the original + * objects, which means that changes to those objects after this method is called will + * affect the values on the animator. If the objects will be mutated externally after + * this method is called, callers should pass a copy of those objects instead. + * *

Since ValueAnimator does not know how to animate between arbitrary Objects, this * factory method also takes a TypeEvaluator object that the ValueAnimator will use * to perform that interpolation. @@ -434,6 +439,11 @@ public class ValueAnimator extends Animator implements AnimationHandler.Animatio * from the target object and property being animated). Therefore, there should typically * be two or more values. * + *

Note: The Object values are stored as references to the original + * objects, which means that changes to those objects after this method is called will + * affect the values on the animator. If the objects will be mutated externally after + * this method is called, callers should pass a copy of those objects instead. + * *

If there are already multiple sets of values defined for this ValueAnimator via more * than one PropertyValuesHolder object, this method will set the values for the first * of those objects.