From 41f041d9986f8a5d45b6cb0b86e881c81a412168 Mon Sep 17 00:00:00 2001 From: Chet Haase Date: Tue, 12 Oct 2010 16:29:28 -0700 Subject: [PATCH] Remove generics from Animator APIs Change the manner of constructing Animator-related objects from constructors via generics to factory methods with type-specific method names. Should improve the proliferation of warnings due to generics issues and make the code more readable (less irrelevant angle brackets Floating around). Change-Id: I7c1776b15f3c9f245c09fb7de6dc005fdba58fe2 --- api/current.xml | 521 ++++++++++++++---- core/java/android/animation/Animator.java | 2 +- .../android/animation/AnimatorInflater.java | 124 +++-- core/java/android/animation/AnimatorSet.java | 10 +- core/java/android/animation/KeyframeSet.java | 80 ++- .../android/animation/LayoutTransition.java | 19 +- .../android/animation/ObjectAnimator.java | 154 +++++- .../animation/PropertyValuesHolder.java | 219 +++++++- .../java/android/animation/ValueAnimator.java | 297 ++++++++-- .../android/widget/AdapterViewAnimator.java | 36 +- core/java/android/widget/StackView.java | 57 +- .../internal/widget/DrawableHolder.java | 19 +- 12 files changed, 1251 insertions(+), 287 deletions(-) diff --git a/api/current.xml b/api/current.xml index 1d84c39e8f743..5f08249298815 100644 --- a/api/current.xml +++ b/api/current.xml @@ -20416,7 +20416,7 @@ - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + @@ -22064,6 +22352,19 @@ + + + + + + + + + + + + + + + + - - - - - + - + (); - for (Keyframe keyframe : keyframes) { - mKeyframes.add(keyframe); - } + mKeyframes.addAll(Arrays.asList(keyframes)); mNumKeyframes = mKeyframes.size(); } + public static KeyframeSet ofInt(int... values) { + int numKeyframes = values.length; + Keyframe keyframes[] = new Keyframe[Math.max(numKeyframes,2)]; + if (numKeyframes == 1) { + keyframes[0] = new Keyframe(0f, (Object) null); + keyframes[1] = new Keyframe(1f, values[0]); + } else { + keyframes[0] = new Keyframe(0f, values[0]); + for (int i = 1; i < numKeyframes; ++i) { + keyframes[i] = new Keyframe((float) i / (numKeyframes - 1), values[i]); + } + } + return new KeyframeSet(keyframes); + } + + public static KeyframeSet ofFloat(float... values) { + int numKeyframes = values.length; + Keyframe keyframes[] = new Keyframe[Math.max(numKeyframes,2)]; + if (numKeyframes == 1) { + keyframes[0] = new Keyframe(0f, (Object) null); + keyframes[1] = new Keyframe(1f, values[0]); + } else { + keyframes[0] = new Keyframe(0f, values[0]); + for (int i = 1; i < numKeyframes; ++i) { + keyframes[i] = new Keyframe((float) i / (numKeyframes - 1), values[i]); + } + } + return new KeyframeSet(keyframes); + } + + public static KeyframeSet ofDouble(double... values) { + int numKeyframes = values.length; + Keyframe keyframes[] = new Keyframe[Math.max(numKeyframes,2)]; + if (numKeyframes == 1) { + keyframes[0] = new Keyframe(0f, (Object) null); + keyframes[1] = new Keyframe(1f, values[0]); + } else { + keyframes[0] = new Keyframe(0f, values[0]); + for (int i = 1; i < numKeyframes; ++i) { + keyframes[i] = new Keyframe((float) i / (numKeyframes - 1), values[i]); + } + } + return new KeyframeSet(keyframes); + } + + public static KeyframeSet ofLong(long... values) { + int numKeyframes = values.length; + Keyframe keyframes[] = new Keyframe[Math.max(numKeyframes,2)]; + if (numKeyframes == 1) { + keyframes[0] = new Keyframe(0f, (Object) null); + keyframes[1] = new Keyframe(1f, values[0]); + } else { + keyframes[0] = new Keyframe(0f, values[0]); + for (int i = 1; i < numKeyframes; ++i) { + keyframes[i] = new Keyframe((float) i / (numKeyframes - 1), values[i]); + } + } + return new KeyframeSet(keyframes); + } + + public static KeyframeSet ofObject(Object... values) { + int numKeyframes = values.length; + Keyframe keyframes[] = new Keyframe[Math.max(numKeyframes,2)]; + if (numKeyframes == 1) { + keyframes[0] = new Keyframe(0f, (Object) null); + keyframes[1] = new Keyframe(1f, values[0]); + } else { + keyframes[0] = new Keyframe(0f, values[0]); + for (int i = 1; i < numKeyframes; ++i) { + keyframes[i] = new Keyframe((float) i / (numKeyframes - 1), values[i]); + } + } + return new KeyframeSet(keyframes); + } + /** * Gets the animated value, given the elapsed fraction of the animation (interpolated by the * animation's interpolator) and the evaluator used to calculate in-between values. This diff --git a/core/java/android/animation/LayoutTransition.java b/core/java/android/animation/LayoutTransition.java index 56ad857a0267e..d843737b1d413 100644 --- a/core/java/android/animation/LayoutTransition.java +++ b/core/java/android/animation/LayoutTransition.java @@ -189,23 +189,24 @@ public class LayoutTransition { public LayoutTransition() { if (defaultChangeIn == null) { // "left" is just a placeholder; we'll put real properties/values in when needed - PropertyValuesHolder pvhLeft = new PropertyValuesHolder("left", 0, 1); - PropertyValuesHolder pvhTop = new PropertyValuesHolder("top", 0, 1); - PropertyValuesHolder pvhRight = new PropertyValuesHolder("right", 0, 1); - PropertyValuesHolder pvhBottom = new PropertyValuesHolder("bottom", 0, 1); - defaultChangeIn = new ObjectAnimator(DEFAULT_DURATION, this, + PropertyValuesHolder pvhLeft = PropertyValuesHolder.ofInt("left", 0, 1); + PropertyValuesHolder pvhTop = PropertyValuesHolder.ofInt("top", 0, 1); + PropertyValuesHolder pvhRight = PropertyValuesHolder.ofInt("right", 0, 1); + PropertyValuesHolder pvhBottom = PropertyValuesHolder.ofInt("bottom", 0, 1); + defaultChangeIn = ObjectAnimator.ofPropertyValuesHolder(this, pvhLeft, pvhTop, pvhRight, pvhBottom); + defaultChangeIn.setDuration(DEFAULT_DURATION); defaultChangeIn.setStartDelay(mChangingAppearingDelay); defaultChangeIn.setInterpolator(mChangingAppearingInterpolator); defaultChangeOut = defaultChangeIn.clone(); defaultChangeOut.setStartDelay(mChangingDisappearingDelay); defaultChangeOut.setInterpolator(mChangingDisappearingInterpolator); - defaultFadeIn = - new ObjectAnimator(DEFAULT_DURATION, this, "alpha", 0f, 1f); + defaultFadeIn = ObjectAnimator.ofFloat(this, "alpha", 0f, 1f); + defaultFadeIn.setDuration(DEFAULT_DURATION); defaultFadeIn.setStartDelay(mAppearingDelay); defaultFadeIn.setInterpolator(mAppearingInterpolator); - defaultFadeOut = - new ObjectAnimator(DEFAULT_DURATION, this, "alpha", 1f, 0f); + defaultFadeOut = ObjectAnimator.ofFloat(this, "alpha", 1f, 0f); + defaultFadeOut.setDuration(DEFAULT_DURATION); defaultFadeOut.setStartDelay(mDisappearingDelay); defaultFadeOut.setInterpolator(mDisappearingInterpolator); } diff --git a/core/java/android/animation/ObjectAnimator.java b/core/java/android/animation/ObjectAnimator.java index 31ddb0b51eb81..135dfdb8c59fd 100644 --- a/core/java/android/animation/ObjectAnimator.java +++ b/core/java/android/animation/ObjectAnimator.java @@ -27,7 +27,7 @@ import java.lang.reflect.Method; * are then determined internally and the animation will call these functions as necessary to * animate the property. */ -public final class ObjectAnimator extends ValueAnimator { +public final class ObjectAnimator extends ValueAnimator { // The target object on which the property exists, set in the constructor private Object mTarget; @@ -122,53 +122,146 @@ public final class ObjectAnimator extends ValueAnimator { * A constructor that takes a single property name and set of values. This constructor is * used in the simple case of animating a single property. * - * @param duration The length of the animation, in milliseconds. * @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. * @param propertyName The name of the property being animated. - * @param values The set of values to animate between. If there is only one value, it - * is assumed to be the final value being animated to, and the initial value will be - * derived on the fly. */ - public ObjectAnimator(long duration, Object target, String propertyName, T...values) { - super(duration, (T[]) values); + private ObjectAnimator(Object target, String propertyName) { mTarget = target; setPropertyName(propertyName); } + /** + * Constructs and returns an ObjectAnimator that animates between int values. A single + * value implies that that value is the one being animated to. However, this is not typically + * useful in a ValueAnimator object because there is no way for the object to determine the + * starting value for the animation (unlike ObjectAnimator, which can derive that value + * from the target object and property being animated). Therefore, there should typically + * be two or more values. + * + * @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. + * @param propertyName The name of the property being animated. + * @param values A set of values that the animation will animate between over time. + * @return A ValueAnimator object that is set up to animate between the given values. + */ + public static ObjectAnimator ofInt(Object target, String propertyName, int... values) { + ObjectAnimator anim = new ObjectAnimator(target, propertyName); + anim.setIntValues(values); + return anim; + } + + /** + * Constructs and returns an ObjectAnimator that animates between float values. A single + * value implies that that value is the one being animated to. However, this is not typically + * useful in a ValueAnimator object because there is no way for the object to determine the + * starting value for the animation (unlike ObjectAnimator, which can derive that value + * from the target object and property being animated). Therefore, there should typically + * be two or more values. + * + * @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. + * @param propertyName The name of the property being animated. + * @param values A set of values that the animation will animate between over time. + * @return A ValueAnimator object that is set up to animate between the given values. + */ + public static ObjectAnimator ofFloat(Object target, String propertyName, float... values) { + ObjectAnimator anim = new ObjectAnimator(target, propertyName); + anim.setFloatValues(values); + return anim; + } + + /** + * Constructs and returns an ObjectAnimator that animates between long values. A single + * value implies that that value is the one being animated to. However, this is not typically + * useful in a ValueAnimator object because there is no way for the object to determine the + * starting value for the animation (unlike ObjectAnimator, which can derive that value + * from the target object and property being animated). Therefore, there should typically + * be two or more values. + * + * @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. + * @param propertyName The name of the property being animated. + * @param values A set of values that the animation will animate between over time. + * @return A ValueAnimator object that is set up to animate between the given values. + */ + public static ObjectAnimator ofLong(Object target, String propertyName, long... values) { + ObjectAnimator anim = new ObjectAnimator(target, propertyName); + anim.setLongValues(values); + return anim; + } + + /** + * Constructs and returns an ObjectAnimator that animates between double values. A single + * value implies that that value is the one being animated to. However, this is not typically + * useful in a ValueAnimator object because there is no way for the object to determine the + * starting value for the animation (unlike ObjectAnimator, which can derive that value + * from the target object and property being animated). Therefore, there should typically + * be two or more values. + * + * @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. + * @param propertyName The name of the property being animated. + * @param values A set of values that the animation will animate between over time. + * @return A ValueAnimator object that is set up to animate between the given values. + */ + public static ObjectAnimator ofDouble(Object target, String propertyName, double... values) { + ObjectAnimator anim = new ObjectAnimator(target, propertyName); + anim.setDoubleValues(values); + return anim; + } + /** * A constructor that takes PropertyValueHolder values. This constructor should * be used when animating several properties at once with the same ObjectAnimator, since * PropertyValuesHolder allows you to associate a set of animation values with a property * name. * - * @param duration The length of the animation, in milliseconds. * @param target The object whose property is to be animated. This object should * have public methods on it called setName(), where name is * the name of the property passed in as the propertyName parameter for * each of the PropertyValuesHolder objects. + * @param propertyName The name of the property being animated. + * @param evaluator A TypeEvaluator that will be called on each animation frame to + * provide the ncessry interpolation between the Object values to derive the animated + * value. * @param values The PropertyValuesHolder objects which hold each the property name and values * to animate that property between. */ - public ObjectAnimator(long duration, Object target, PropertyValuesHolder...values) { - super(duration); - setValues(values); - mTarget = target; + public static ObjectAnimator ofObject(Object target, String propertyName, + TypeEvaluator evaluator, Object... values) { + ObjectAnimator anim = new ObjectAnimator(target, propertyName); + anim.setObjectValues(values); + anim.setEvaluator(evaluator); + return anim; } - @Override - public void setValues(T... values) { - if (mValues == null || mValues.length == 0) { - // No values yet - this animator is being constructed piecemeal. Init the values with - // whatever the current propertyName is - setValues(new PropertyValuesHolder[]{ - new PropertyValuesHolder(mPropertyName, (Object[])values)}); - } else { - super.setValues((T[]) values); - } + /** + * Constructs and returns an ObjectAnimator that animates between the sets of values + * specifed in PropertyValueHolder objects. This variant should + * be used when animating several properties at once with the same ObjectAnimator, since + * PropertyValuesHolder allows you to associate a set of animation values with a property + * name. + * + * @param target The object whose property is to be animated. This object should + * have public methods on it called setName(), where name is + * the name of the property passed in as the propertyName parameter for + * each of the PropertyValuesHolder objects. + * @param values A set of PropertyValuesHolder objects whose values will be animated + * between over time. + * @return A ValueAnimator object that is set up to animate between the given values. + */ + public static ObjectAnimator ofPropertyValuesHolder(Object target, + PropertyValuesHolder... values) { + ObjectAnimator anim = new ObjectAnimator(); + anim.setValues(values); + return anim; } - /** * This function is called immediately before processing the first animation * frame of an animation. If there is a nonzero startDelay, the @@ -194,6 +287,21 @@ public final class ObjectAnimator extends ValueAnimator { } } + /** + * Sets the length of the animation. The default duration is 300 milliseconds. + * + * @param duration The length of the animation, in milliseconds. + * @return ObjectAnimator The object called with setDuration(). This return + * value makes it easier to compose statements together that construct and then set the + * duration, as in + * ObjectAnimator.ofInt(target, propertyName, 0, 10).setDuration(500).start(). + */ + @Override + public ObjectAnimator setDuration(long duration) { + super.setDuration(duration); + return this; + } + /** * The target object whose property will be animated by this animation diff --git a/core/java/android/animation/PropertyValuesHolder.java b/core/java/android/animation/PropertyValuesHolder.java index 1d46123db4375..d546f310718c6 100644 --- a/core/java/android/animation/PropertyValuesHolder.java +++ b/core/java/android/animation/PropertyValuesHolder.java @@ -30,7 +30,7 @@ import java.util.concurrent.locks.ReentrantReadWriteLock; * animations with ValueAnimator or ObjectAnimator that operate on several different properties * in parallel. */ -public class PropertyValuesHolder implements Cloneable { +public class PropertyValuesHolder implements Cloneable { /** * The name of the property associated with the values. This need not be a real property, @@ -118,22 +118,88 @@ public class PropertyValuesHolder implements Cloneable { private Object mAnimatedValue; /** - * Constructs a PropertyValuesHolder object with just a set of values. This constructor - * is typically not used when animating objects with ObjectAnimator, because that - * object needs distinct and meaningful property names. Simpler animations of one - * set of values using ValueAnimator may use this constructor, however, because no - * distinguishing name is needed. - * @param values The set of values to animate between. If there is only one value, it - * is assumed to be the final value being animated to, and the initial value will be - * derived on the fly. + * Internal utility constructor, used by the factory methods to set the property name. + * @param propertyName The name of the property for this holder. */ - public PropertyValuesHolder(T...values) { - this(null, values); + private PropertyValuesHolder(String propertyName) { + mPropertyName = propertyName; } /** - * Constructs a PropertyValuesHolder object with the specified property name and set of - * values. These values can be of any type, but the type should be consistent so that + * Constructs and returns a PropertyValuesHolder with a given property name and + * set of int values. + * @param propertyName The name of the property being animated. + * @param values The values that the named property will animate between. + * @return PropertyValuesHolder The constructed PropertyValuesHolder object. + */ + public static PropertyValuesHolder ofInt(String propertyName, int... values) { + PropertyValuesHolder pvh = new PropertyValuesHolder(propertyName); + pvh.setIntValues(values); + return pvh; + } + + /** + * Constructs and returns a PropertyValuesHolder with a given property name and + * set of float values. + * @param propertyName The name of the property being animated. + * @param values The values that the named property will animate between. + * @return PropertyValuesHolder The constructed PropertyValuesHolder object. + */ + public static PropertyValuesHolder ofFloat(String propertyName, float... values) { + PropertyValuesHolder pvh = new PropertyValuesHolder(propertyName); + pvh.setFloatValues(values); + return pvh; + } + + /** + * Constructs and returns a PropertyValuesHolder with a given property name and + * set of double values. + * @param propertyName The name of the property being animated. + * @param values The values that the named property will animate between. + * @return PropertyValuesHolder The constructed PropertyValuesHolder object. + */ + public static PropertyValuesHolder ofDouble(String propertyName, double... values) { + PropertyValuesHolder pvh = new PropertyValuesHolder(propertyName); + pvh.setDoubleValues(values); + return pvh; + } + + /** + * Constructs and returns a PropertyValuesHolder with a given property name and + * set of long values. + * @param propertyName The name of the property being animated. + * @param values The values that the named property will animate between. + * @return PropertyValuesHolder The constructed PropertyValuesHolder object. + */ + public static PropertyValuesHolder ofLong(String propertyName, long... values) { + PropertyValuesHolder pvh = new PropertyValuesHolder(propertyName); + pvh.setLongValues(values); + return pvh; + } + + /** + * Constructs and returns a PropertyValuesHolder with a given property name and + * set of Object values. This variant also takes a TypeEvaluator because the system + * cannot interpolate between objects of unknown type. + * + * @param propertyName The name of the property being animated. + * @param evaluator A TypeEvaluator that will be called on each animation frame to + * provide the ncessry interpolation between the Object values to derive the animated + * value. + * @param values The values that the named property will animate between. + * @return PropertyValuesHolder The constructed PropertyValuesHolder object. + */ + public static PropertyValuesHolder ofObject(String propertyName, TypeEvaluator evaluator, + Object... values) { + PropertyValuesHolder pvh = new PropertyValuesHolder(propertyName); + pvh.setObjectValues(values); + pvh.setEvaluator(evaluator); + return pvh; + } + + /** + * Constructs and returns a PropertyValuesHolder object with the specified property name and set + * of values. These values can be of any type, but the type should be consistent so that * an appropriate {@link android.animation.TypeEvaluator} can be found that matches * the common type. *

If there is only one value, it is assumed to be the end value of an animation, @@ -151,9 +217,120 @@ public class PropertyValuesHolder implements Cloneable { * ValueAnimator object. * @param values The set of values to animate between. */ - public PropertyValuesHolder(String propertyName, T... values) { - mPropertyName = propertyName; - setValues(values); + public static PropertyValuesHolder ofKeyframe(String propertyName, Keyframe... values) { + PropertyValuesHolder pvh = new PropertyValuesHolder(propertyName); + pvh.setKeyframes(values); + return pvh; + } + + /** + * Set the animated values for this object to this set of ints. + * If there is only one value, it is assumed to be the end value of an animation, + * and an initial value will be derived, if possible, by calling a getter function + * on the object. Also, if any value is null, the value will be filled in when the animation + * starts in the same way. This mechanism of automatically getting null values only works + * if the PropertyValuesHolder object is used in conjunction + * {@link ObjectAnimator}, and with a getter function either + * derived automatically from propertyName or set explicitly via + * {@link #setGetter(java.lang.reflect.Method)}, since otherwise PropertyValuesHolder has + * no way of determining what the value should be. + * + * @param values One or more values that the animation will animate between. + */ + public void setIntValues(int... values) { + mValueType = int.class; + mKeyframeSet = KeyframeSet.ofInt(values); + } + + /** + * Set the animated values for this object to this set of floats. + * If there is only one value, it is assumed to be the end value of an animation, + * and an initial value will be derived, if possible, by calling a getter function + * on the object. Also, if any value is null, the value will be filled in when the animation + * starts in the same way. This mechanism of automatically getting null values only works + * if the PropertyValuesHolder object is used in conjunction + * {@link ObjectAnimator}, and with a getter function either + * derived automatically from propertyName or set explicitly via + * {@link #setGetter(java.lang.reflect.Method)}, since otherwise PropertyValuesHolder has + * no way of determining what the value should be. + * + * @param values One or more values that the animation will animate between. + */ + public void setFloatValues(float... values) { + mValueType = float.class; + mKeyframeSet = KeyframeSet.ofFloat(values); + } + + /** + * Set the animated values for this object to this set of doubles. + * If there is only one value, it is assumed to be the end value of an animation, + * and an initial value will be derived, if possible, by calling a getter function + * on the object. Also, if any value is null, the value will be filled in when the animation + * starts in the same way. This mechanism of automatically getting null values only works + * if the PropertyValuesHolder object is used in conjunction + * {@link ObjectAnimator}, and with a getter function either + * derived automatically from propertyName or set explicitly via + * {@link #setGetter(java.lang.reflect.Method)}, since otherwise PropertyValuesHolder has + * no way of determining what the value should be. + * + * @param values One or more values that the animation will animate between. + */ + public void setDoubleValues(double... values) { + mValueType = double.class; + mKeyframeSet = KeyframeSet.ofDouble(values); + } + + /** + * Set the animated values for this object to this set of longs. + * If there is only one value, it is assumed to be the end value of an animation, + * and an initial value will be derived, if possible, by calling a getter function + * on the object. Also, if any value is null, the value will be filled in when the animation + * starts in the same way. This mechanism of automatically getting null values only works + * if the PropertyValuesHolder object is used in conjunction + * {@link ObjectAnimator}, and with a getter function either + * derived automatically from propertyName or set explicitly via + * {@link #setGetter(java.lang.reflect.Method)}, since otherwise PropertyValuesHolder has + * no way of determining what the value should be. + * + * @param values One or more values that the animation will animate between. + */ + public void setLongValues(long... values) { + mValueType = long.class; + mKeyframeSet = KeyframeSet.ofLong(values); + } + + /** + * Set the animated values for this object to this set of Keyframes. + * + * @param values One or more values that the animation will animate between. + */ + public void setKeyframes(Keyframe... values) { + int numKeyframes = values.length; + Keyframe keyframes[] = new Keyframe[Math.max(numKeyframes,2)]; + mValueType = ((Keyframe)values[0]).getType(); + for (int i = 0; i < numKeyframes; ++i) { + keyframes[i] = (Keyframe)values[i]; + } + mKeyframeSet = new KeyframeSet(keyframes); + } + + /** + * Set the animated values for this object to this set of Objects. + * If there is only one value, it is assumed to be the end value of an animation, + * and an initial value will be derived, if possible, by calling a getter function + * on the object. Also, if any value is null, the value will be filled in when the animation + * starts in the same way. This mechanism of automatically getting null values only works + * if the PropertyValuesHolder object is used in conjunction + * {@link ObjectAnimator}, and with a getter function either + * derived automatically from propertyName or set explicitly via + * {@link #setGetter(java.lang.reflect.Method)}, since otherwise PropertyValuesHolder has + * no way of determining what the value should be. + * + * @param values One or more values that the animation will animate between. + */ + public void setObjectValues(Object... values) { + mValueType = values[0].getClass(); + mKeyframeSet = KeyframeSet.ofObject(values); } /** @@ -169,6 +346,7 @@ public class PropertyValuesHolder implements Cloneable { * no way of determining what the value should be. * @param values The set of values to animate between. */ + /* public void setValues(T... values) { int numKeyframes = values.length; for (int i = 0; i < numKeyframes; ++i) { @@ -210,6 +388,7 @@ public class PropertyValuesHolder implements Cloneable { } mKeyframeSet = new KeyframeSet(keyframes); } + */ @@ -351,7 +530,7 @@ public class PropertyValuesHolder implements Cloneable { setupGetter(targetClass); } try { - kf.setValue((T) mGetter.invoke(target)); + kf.setValue(mGetter.invoke(target)); } catch (InvocationTargetException e) { Log.e("PropertyValuesHolder", e.toString()); } catch (IllegalAccessException e) { @@ -374,7 +553,7 @@ public class PropertyValuesHolder implements Cloneable { Class targetClass = target.getClass(); setupGetter(targetClass); } - kf.setValue((T) mGetter.invoke(target)); + kf.setValue(mGetter.invoke(target)); } catch (InvocationTargetException e) { Log.e("PropertyValuesHolder", e.toString()); } catch (IllegalAccessException e) { @@ -414,9 +593,7 @@ public class PropertyValuesHolder implements Cloneable { for (int i = 0; i < numKeyframes; ++i) { newKeyframes[i] = keyframes.get(i).clone(); } - PropertyValuesHolder pvhClone = new PropertyValuesHolder(mPropertyName, - (Object[]) newKeyframes); - return pvhClone; + return PropertyValuesHolder.ofKeyframe(mPropertyName, newKeyframes); } /** * Internal function to set the value on the target object, using the setter set up diff --git a/core/java/android/animation/ValueAnimator.java b/core/java/android/animation/ValueAnimator.java index a6f061d76747c..8aa29958a6cc8 100755 --- a/core/java/android/animation/ValueAnimator.java +++ b/core/java/android/animation/ValueAnimator.java @@ -37,7 +37,7 @@ import java.util.HashMap; * out of an animation. This behavior can be changed by calling * {@link ValueAnimator#setInterpolator(TimeInterpolator)}.

*/ -public class ValueAnimator extends Animator { +public class ValueAnimator extends Animator { /** * Internal constants @@ -154,7 +154,7 @@ public class ValueAnimator extends Animator { // // How long the animation should last in ms - private long mDuration; + private long mDuration = 300; // The amount of time in ms to delay starting the animation after start() is called private long mStartDelay = 0; @@ -218,28 +218,261 @@ public class ValueAnimator extends Animator { /** * Creates a new ValueAnimator object. This default constructor is primarily for - * use internally; the other constructors which take parameters are more generally + * use internally; the factory methods which take parameters are more generally * useful. */ public ValueAnimator() { } /** - * Constructs an ValueAnimator object with the specified duration and set of - * values. If the values are a set of PropertyValuesHolder objects, then these objects - * define the potentially multiple properties being animated and the values the properties are - * animated between. Otherwise, the values define a single set of values animated between. + * Constructs and returns a ValueAnimator that animates between int values. A single + * value implies that that value is the one being animated to. However, this is not typically + * useful in a ValueAnimator object because there is no way for the object to determine the + * starting value for the animation (unlike ObjectAnimator, which can derive that value + * from the target object and property being animated). Therefore, there should typically + * be two or more values. * - * @param duration The length of the animation, in milliseconds. - * @param values The set of values to animate between. If these values are not - * PropertyValuesHolder objects, then there should be more than one value, since the values - * determine the interval to animate between. + * @param values A set of values that the animation will animate between over time. + * @return A ValueAnimator object that is set up to animate between the given values. */ - public ValueAnimator(long duration, T...values) { - mDuration = duration; - if (values.length > 0) { - setValues(values); + public static ValueAnimator ofInt(int... values) { + ValueAnimator anim = new ValueAnimator(); + anim.setIntValues(values); + return anim; + } + + /** + * Constructs and returns a ValueAnimator that animates between float values. A single + * value implies that that value is the one being animated to. However, this is not typically + * useful in a ValueAnimator object because there is no way for the object to determine the + * starting value for the animation (unlike ObjectAnimator, which can derive that value + * from the target object and property being animated). Therefore, there should typically + * be two or more values. + * + * @param values A set of values that the animation will animate between over time. + * @return A ValueAnimator object that is set up to animate between the given values. + */ + public static ValueAnimator ofFloat(float... values) { + ValueAnimator anim = new ValueAnimator(); + anim.setFloatValues(values); + return anim; + } + + /** + * Constructs and returns a ValueAnimator that animates between double values. A single + * value implies that that value is the one being animated to. However, this is not typically + * useful in a ValueAnimator object because there is no way for the object to determine the + * starting value for the animation (unlike ObjectAnimator, which can derive that value + * from the target object and property being animated). Therefore, there should typically + * be two or more values. + * + * @param values A set of values that the animation will animate between over time. + * @return A ValueAnimator object that is set up to animate between the given values. + */ + public static ValueAnimator ofDouble(double... values) { + ValueAnimator anim = new ValueAnimator(); + anim.setDoubleValues(values); + return anim; + } + + /** + * Constructs and returns a ValueAnimator that animates between long values. A single + * value implies that that value is the one being animated to. However, this is not typically + * useful in a ValueAnimator object because there is no way for the object to determine the + * starting value for the animation (unlike ObjectAnimator, which can derive that value + * from the target object and property being animated). Therefore, there should typically + * be two or more values. + * + * @param values A set of values that the animation will animate between over time. + * @return A ValueAnimator object that is set up to animate between the given values. + */ + public static ValueAnimator ofLong(long... values) { + ValueAnimator anim = new ValueAnimator(); + anim.setLongValues(values); + return anim; + } + + /** + * Constructs and returns a ValueAnimator that animates between the values + * specified in the PropertyValuesHolder objects. + * + * @param values A set of PropertyValuesHolder objects whose values will be animated + * between over time. + * @return A ValueAnimator object that is set up to animate between the given values. + */ + public static ValueAnimator ofPropertyValuesHolder(PropertyValuesHolder... values) { + ValueAnimator anim = new ValueAnimator(); + anim.setValues(values); + return anim; + } + /** + * Constructs and returns a ValueAnimator that animates between Object values. A single + * value implies that that value is the one being animated to. However, this is not typically + * useful in a ValueAnimator object because there is no way for the object to determine the + * starting value for the animation (unlike ObjectAnimator, which can derive that value + * from the target object and property being animated). Therefore, there should typically + * be two or more values. + * + *

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. + * + * @param evaluator A TypeEvaluator that will be called on each animation frame to + * provide the ncessry interpolation between the Object values to derive the animated + * value. + * @param values A set of values that the animation will animate between over time. + * @return A ValueAnimator object that is set up to animate between the given values. + */ + public static ValueAnimator ofObject(TypeEvaluator evaluator, Object... values) { + ValueAnimator anim = new ValueAnimator(); + anim.setObjectValues(values); + anim.setEvaluator(evaluator); + return anim; + } + + /** + * Sets int values that will be animated between. A single + * value implies that that value is the one being animated to. However, this is not typically + * useful in a ValueAnimator object because there is no way for the object to determine the + * starting value for the animation (unlike ObjectAnimator, which can derive that value + * from the target object and property being animated). Therefore, there should typically + * be two or more values. + * + *

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.

+ * + * @param values A set of values that the animation will animate between over time. + */ + public void setIntValues(int... values) { + if (values == null || values.length == 0) { + return; } + if (mValues == null || mValues.length == 0) { + setValues(new PropertyValuesHolder[]{PropertyValuesHolder.ofInt("", values)}); + } else { + PropertyValuesHolder valuesHolder = mValues[0]; + valuesHolder.setIntValues(values); + } + // New property/values/target should cause re-initialization prior to starting + mInitialized = false; + } + + /** + * Sets float values that will be animated between. A single + * value implies that that value is the one being animated to. However, this is not typically + * useful in a ValueAnimator object because there is no way for the object to determine the + * starting value for the animation (unlike ObjectAnimator, which can derive that value + * from the target object and property being animated). Therefore, there should typically + * be two or more values. + * + *

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.

+ * + * @param values A set of values that the animation will animate between over time. + */ + public void setFloatValues(float... values) { + if (values == null || values.length == 0) { + return; + } + if (mValues == null || mValues.length == 0) { + setValues(new PropertyValuesHolder[]{PropertyValuesHolder.ofFloat("", values)}); + } else { + PropertyValuesHolder valuesHolder = mValues[0]; + valuesHolder.setFloatValues(values); + } + // New property/values/target should cause re-initialization prior to starting + mInitialized = false; + } + + /** + * Sets long values that will be animated between. A single + * value implies that that value is the one being animated to. However, this is not typically + * useful in a ValueAnimator object because there is no way for the object to determine the + * starting value for the animation (unlike ObjectAnimator, which can derive that value + * from the target object and property being animated). Therefore, there should typically + * be two or more values. + * + *

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.

+ * + * @param values A set of values that the animation will animate between over time. + */ + public void setLongValues(long... values) { + if (values == null || values.length == 0) { + return; + } + if (mValues == null || mValues.length == 0) { + setValues(new PropertyValuesHolder[]{PropertyValuesHolder.ofLong("", values)}); + } else { + PropertyValuesHolder valuesHolder = mValues[0]; + valuesHolder.setLongValues(values); + } + // New property/values/target should cause re-initialization prior to starting + mInitialized = false; + } + + /** + * Sets double values that will be animated between. A single + * value implies that that value is the one being animated to. However, this is not typically + * useful in a ValueAnimator object because there is no way for the object to determine the + * starting value for the animation (unlike ObjectAnimator, which can derive that value + * from the target object and property being animated). Therefore, there should typically + * be two or more values. + * + *

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.

+ * + * @param values A set of values that the animation will animate between over time. + */ + public void setDoubleValues(double... values) { + if (values == null || values.length == 0) { + return; + } + if (mValues == null || mValues.length == 0) { + setValues(new PropertyValuesHolder[]{PropertyValuesHolder.ofDouble("", values)}); + } else { + PropertyValuesHolder valuesHolder = mValues[0]; + valuesHolder.setDoubleValues(values); + } + // New property/values/target should cause re-initialization prior to starting + mInitialized = false; + } + + /** + * Sets the values to animate between for this animation. A single + * value implies that that value is the one being animated to. However, this is not typically + * useful in a ValueAnimator object because there is no way for the object to determine the + * starting value for the animation (unlike ObjectAnimator, which can derive that value + * from the target object and property being animated). Therefore, there should typically + * be two or more values. + * + *

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.

+ * + *

There should be a TypeEvaluator set on the ValueAnimator that knows how to interpolate + * between these value objects. ValueAnimator only knows how to interpolate between the + * primitive types specified in the other setValues() methods.

+ * + * @param values The set of values to animate between. + */ + public void setObjectValues(Object... values) { + if (values == null || values.length == 0) { + return; + } + if (mValues == null || mValues.length == 0) { + setValues(new PropertyValuesHolder[]{PropertyValuesHolder.ofObject("", + (TypeEvaluator)null, values)}); + } else { + PropertyValuesHolder valuesHolder = mValues[0]; + valuesHolder.setObjectValues(values); + } + // New property/values/target should cause re-initialization prior to starting + mInitialized = false; } /** @@ -274,30 +507,6 @@ public class ValueAnimator extends Animator { return mValues; } - /** - * Sets the values to animate between for this animation. If values is - * a set of PropertyValuesHolder objects, these objects will become the set of properties - * animated and the values that those properties are animated between. Otherwise, this method - * will set only one set of values for the ValueAnimator. Also, if the values are not - * PropertyValuesHolder objects and if there are already multiple sets of - * values defined for this ValueAnimator via - * more than one PropertyValuesHolder objects, this method will set the values for - * the first of those objects. - * - * @param values The set of values to animate between. - */ - public void setValues(T... values) { - if (mValues == null || mValues.length == 0) { - setValues(new PropertyValuesHolder[]{ - new PropertyValuesHolder("", (Object[])values)}); - } else { - PropertyValuesHolder valuesHolder = mValues[0]; - valuesHolder.setValues(values); - } - // New property/values/target should cause re-initialization prior to starting - mInitialized = false; - } - /** * This function is called immediately before processing the first animation * frame of an animation. If there is a nonzero startDelay, the @@ -321,16 +530,20 @@ public class ValueAnimator extends Animator { /** - * Sets the length of the animation. + * Sets the length of the animation. The default duration is 300 milliseconds. * * @param duration The length of the animation, in milliseconds. + * @return ValueAnimator The object called with setDuration(). This return + * value makes it easier to compose statements together that construct and then set the + * duration, as in ValueAnimator.ofInt(0, 10).setDuration(500).start(). */ - public void setDuration(long duration) { + public ValueAnimator setDuration(long duration) { mDuration = duration; + return this; } /** - * Gets the length of the animation. + * Gets the length of the animation. The default duration is 300 milliseconds. * * @return The length of the animation, in milliseconds. */ diff --git a/core/java/android/widget/AdapterViewAnimator.java b/core/java/android/widget/AdapterViewAnimator.java index b7b1a2309efb5..b5934b03c0967 100644 --- a/core/java/android/widget/AdapterViewAnimator.java +++ b/core/java/android/widget/AdapterViewAnimator.java @@ -138,8 +138,8 @@ public abstract class AdapterViewAnimator extends AdapterView /** * In and out animations. */ - ObjectAnimator mInAnimation; - ObjectAnimator mOutAnimation; + ObjectAnimator mInAnimation; + ObjectAnimator mOutAnimation; private ArrayList mViewsToBringToFront; @@ -246,12 +246,16 @@ public abstract class AdapterViewAnimator extends AdapterView } } - ObjectAnimator getDefaultInAnimation() { - return new ObjectAnimator(DEFAULT_ANIMATION_DURATION, null, "alpha", 0.0f, 1.0f); + ObjectAnimator getDefaultInAnimation() { + ObjectAnimator anim = ObjectAnimator.ofFloat(null, "alpha", 0.0f, 1.0f); + anim.setDuration(DEFAULT_ANIMATION_DURATION); + return anim; } - ObjectAnimator getDefaultOutAnimation() { - return new ObjectAnimator(DEFAULT_ANIMATION_DURATION, null, "alpha", 1.0f, 0.0f); + ObjectAnimator getDefaultOutAnimation() { + ObjectAnimator anim = ObjectAnimator.ofFloat(null, "alpha", 1.0f, 0.0f); + anim.setDuration(DEFAULT_ANIMATION_DURATION); + return anim; } /** @@ -692,10 +696,10 @@ public abstract class AdapterViewAnimator extends AdapterView * * @return An Animation or null if none is set. * - * @see #setInAnimation(android.view.animation.Animation) + * @see #setInAnimation(android.animation.ObjectAnimator) * @see #setInAnimation(android.content.Context, int) */ - public ObjectAnimator getInAnimation() { + public ObjectAnimator getInAnimation() { return mInAnimation; } @@ -707,7 +711,7 @@ public abstract class AdapterViewAnimator extends AdapterView * @see #getInAnimation() * @see #setInAnimation(android.content.Context, int) */ - public void setInAnimation(ObjectAnimator inAnimation) { + public void setInAnimation(ObjectAnimator inAnimation) { mInAnimation = inAnimation; } @@ -716,10 +720,10 @@ public abstract class AdapterViewAnimator extends AdapterView * * @return An Animation or null if none is set. * - * @see #setOutAnimation(android.view.animation.Animation) + * @see #setOutAnimation(android.animation.ObjectAnimator) * @see #setOutAnimation(android.content.Context, int) */ - public ObjectAnimator getOutAnimation() { + public ObjectAnimator getOutAnimation() { return mOutAnimation; } @@ -731,7 +735,7 @@ public abstract class AdapterViewAnimator extends AdapterView * @see #getOutAnimation() * @see #setOutAnimation(android.content.Context, int) */ - public void setOutAnimation(ObjectAnimator outAnimation) { + public void setOutAnimation(ObjectAnimator outAnimation) { mOutAnimation = outAnimation; } @@ -742,10 +746,10 @@ public abstract class AdapterViewAnimator extends AdapterView * @param resourceID The resource id of the animation. * * @see #getInAnimation() - * @see #setInAnimation(android.view.animation.Animation) + * @see #setInAnimation(android.animation.ObjectAnimator) */ public void setInAnimation(Context context, int resourceID) { - setInAnimation((ObjectAnimator) AnimatorInflater.loadAnimator(context, resourceID)); + setInAnimation((ObjectAnimator) AnimatorInflater.loadAnimator(context, resourceID)); } /** @@ -755,10 +759,10 @@ public abstract class AdapterViewAnimator extends AdapterView * @param resourceID The resource id of the animation. * * @see #getOutAnimation() - * @see #setOutAnimation(android.view.animation.Animation) + * @see #setOutAnimation(android.animation.ObjectAnimator) */ public void setOutAnimation(Context context, int resourceID) { - setOutAnimation((ObjectAnimator) AnimatorInflater.loadAnimator(context, resourceID)); + setOutAnimation((ObjectAnimator) AnimatorInflater.loadAnimator(context, resourceID)); } /** diff --git a/core/java/android/widget/StackView.java b/core/java/android/widget/StackView.java index f0954e2dbea58..7e01506378509 100644 --- a/core/java/android/widget/StackView.java +++ b/core/java/android/widget/StackView.java @@ -175,8 +175,8 @@ public class StackView extends AdapterViewAnimator { } view.setVisibility(VISIBLE); - ObjectAnimator fadeIn = new ObjectAnimator(DEFAULT_ANIMATION_DURATION, - view, "alpha", view.getAlpha(), 1.0f); + ObjectAnimator fadeIn = ObjectAnimator.ofFloat(view, "alpha", view.getAlpha(), 1.0f); + fadeIn.setDuration(DEFAULT_ANIMATION_DURATION); fadeIn.start(); } else if (fromIndex == mNumActiveViews - 1 && toIndex == mNumActiveViews - 2) { // Slide item in @@ -186,12 +186,11 @@ public class StackView extends AdapterViewAnimator { int duration = Math.round(mStackSlider.getDurationForNeutralPosition(mYVelocity)); StackSlider animationSlider = new StackSlider(mStackSlider); - PropertyValuesHolder slideInY = - new PropertyValuesHolder("YProgress", 0.0f); - PropertyValuesHolder slideInX = - new PropertyValuesHolder("XProgress", 0.0f); - ObjectAnimator pa = new ObjectAnimator(duration, animationSlider, + PropertyValuesHolder slideInY = PropertyValuesHolder.ofFloat("YProgress", 0.0f); + PropertyValuesHolder slideInX = PropertyValuesHolder.ofFloat("XProgress", 0.0f); + ObjectAnimator pa = ObjectAnimator.ofPropertyValuesHolder(animationSlider, slideInX, slideInY); + pa.setDuration(duration); pa.setInterpolator(new LinearInterpolator()); pa.start(); } else if (fromIndex == mNumActiveViews - 2 && toIndex == mNumActiveViews - 1) { @@ -201,12 +200,11 @@ public class StackView extends AdapterViewAnimator { int duration = Math.round(mStackSlider.getDurationForOffscreenPosition(mYVelocity)); StackSlider animationSlider = new StackSlider(mStackSlider); - PropertyValuesHolder slideOutY = - new PropertyValuesHolder("YProgress", 1.0f); - PropertyValuesHolder slideOutX = - new PropertyValuesHolder("XProgress", 0.0f); - ObjectAnimator pa = new ObjectAnimator(duration, animationSlider, - slideOutX, slideOutY); + PropertyValuesHolder slideOutY = PropertyValuesHolder.ofFloat("YProgress", 1.0f); + PropertyValuesHolder slideOutX = PropertyValuesHolder.ofFloat("XProgress", 0.0f); + ObjectAnimator pa = ObjectAnimator.ofPropertyValuesHolder(animationSlider, + slideOutX, slideOutY); + pa.setDuration(duration); pa.setInterpolator(new LinearInterpolator()); pa.start(); } else if (fromIndex == -1 && toIndex == mNumActiveViews - 1) { @@ -217,8 +215,8 @@ public class StackView extends AdapterViewAnimator { lp.setVerticalOffset(-mSlideAmount); } else if (toIndex == -1) { // Fade item out - ObjectAnimator fadeOut = new ObjectAnimator - (DEFAULT_ANIMATION_DURATION, view, "alpha", view.getAlpha(), 0.0f); + ObjectAnimator fadeOut = ObjectAnimator.ofFloat(view, "alpha", view.getAlpha(), 0.0f); + fadeOut.setDuration(DEFAULT_ANIMATION_DURATION); fadeOut.start(); } @@ -236,8 +234,8 @@ public class StackView extends AdapterViewAnimator { float r = (index * 1.0f) / (mNumActiveViews - 2); float scale = 1 - PERSPECTIVE_SCALE_FACTOR * (1 - r); - PropertyValuesHolder scaleX = new PropertyValuesHolder("scaleX", scale); - PropertyValuesHolder scaleY = new PropertyValuesHolder("scaleY", scale); + PropertyValuesHolder scaleX = PropertyValuesHolder.ofFloat("scaleX", scale); + PropertyValuesHolder scaleY = PropertyValuesHolder.ofFloat("scaleY", scale); r = (float) Math.pow(r, 2); @@ -247,9 +245,9 @@ public class StackView extends AdapterViewAnimator { (mMeasuredHeight * (1 - PERSPECTIVE_SHIFT_FACTOR) / 2.0f); float transY = perspectiveTranslation + scaleShiftCorrection; - PropertyValuesHolder translationY = - new PropertyValuesHolder("translationY", transY); - ObjectAnimator pa = new ObjectAnimator(100, view, scaleX, scaleY, translationY); + PropertyValuesHolder translationY = PropertyValuesHolder.ofFloat("translationY", transY); + ObjectAnimator pa = ObjectAnimator.ofPropertyValuesHolder(view, scaleX, scaleY, translationY); + pa.setDuration(100); pa.start(); } @@ -538,12 +536,11 @@ public class StackView extends AdapterViewAnimator { } StackSlider animationSlider = new StackSlider(mStackSlider); - PropertyValuesHolder snapBackY = - new PropertyValuesHolder("YProgress", finalYProgress); - PropertyValuesHolder snapBackX = - new PropertyValuesHolder("XProgress", 0.0f); - ObjectAnimator pa = new ObjectAnimator(duration, animationSlider, + PropertyValuesHolder snapBackY = PropertyValuesHolder.ofFloat("YProgress", finalYProgress); + PropertyValuesHolder snapBackX = PropertyValuesHolder.ofFloat("XProgress", 0.0f); + ObjectAnimator pa = ObjectAnimator.ofPropertyValuesHolder(animationSlider, snapBackX, snapBackY); + pa.setDuration(duration); pa.setInterpolator(new LinearInterpolator()); pa.start(); } else if (mSwipeGestureType == GESTURE_SLIDE_DOWN) { @@ -557,12 +554,12 @@ public class StackView extends AdapterViewAnimator { } StackSlider animationSlider = new StackSlider(mStackSlider); - PropertyValuesHolder snapBackY = - new PropertyValuesHolder("YProgress", finalYProgress); - PropertyValuesHolder snapBackX = - new PropertyValuesHolder("XProgress", 0.0f); - ObjectAnimator pa = new ObjectAnimator(duration, animationSlider, + PropertyValuesHolder snapBackY = + PropertyValuesHolder.ofFloat("YProgress",finalYProgress); + PropertyValuesHolder snapBackX = PropertyValuesHolder.ofFloat("XProgress", 0.0f); + ObjectAnimator pa = ObjectAnimator.ofPropertyValuesHolder(animationSlider, snapBackX, snapBackY); + pa.setDuration(duration); pa.start(); } diff --git a/core/java/com/android/internal/widget/DrawableHolder.java b/core/java/com/android/internal/widget/DrawableHolder.java index d53860cd2d797..958cabb6edd4f 100644 --- a/core/java/com/android/internal/widget/DrawableHolder.java +++ b/core/java/com/android/internal/widget/DrawableHolder.java @@ -41,8 +41,8 @@ public class DrawableHolder implements AnimatorListener { private float mScaleY = 1.0f; private BitmapDrawable mDrawable; private float mAlpha = 1f; - private ArrayList> mAnimators = new ArrayList>(); - private ArrayList> mNeedToStart = new ArrayList>(); + private ArrayList mAnimators = new ArrayList(); + private ArrayList mNeedToStart = new ArrayList(); public DrawableHolder(BitmapDrawable drawable) { this(drawable, 0.0f, 0.0f); @@ -67,12 +67,13 @@ public class DrawableHolder implements AnimatorListener { * @param toValue the target value * @param replace if true, replace the current animation with this one. */ - public ObjectAnimator addAnimTo(long duration, long delay, + public ObjectAnimator addAnimTo(long duration, long delay, String property, float toValue, boolean replace) { if (replace) removeAnimationFor(property); - ObjectAnimator anim = new ObjectAnimator(duration, this, property, toValue); + ObjectAnimator anim = ObjectAnimator.ofFloat(this, property, toValue); + anim.setDuration(duration); anim.setStartDelay(delay); anim.setInterpolator(EASE_OUT_INTERPOLATOR); this.addAnimation(anim, replace); @@ -86,8 +87,8 @@ public class DrawableHolder implements AnimatorListener { * @param property */ public void removeAnimationFor(String property) { - ArrayList> removalList = new ArrayList>(); - for (ObjectAnimator currentAnim : mAnimators) { + ArrayList removalList = new ArrayList(); + for (ObjectAnimator currentAnim : mAnimators) { if (property.equals(currentAnim.getPropertyName())) { currentAnim.cancel(); removalList.add(currentAnim); @@ -101,7 +102,7 @@ public class DrawableHolder implements AnimatorListener { * Stops all animations and removes them from the list. */ public void clearAnimations() { - for (ObjectAnimator currentAnim : mAnimators) { + for (ObjectAnimator currentAnim : mAnimators) { currentAnim.cancel(); } mAnimators.clear(); @@ -114,7 +115,7 @@ public class DrawableHolder implements AnimatorListener { * @param overwrite * @return */ - private DrawableHolder addAnimation(ObjectAnimator anim, boolean overwrite) { + private DrawableHolder addAnimation(ObjectAnimator anim, boolean overwrite) { if (anim != null) mAnimators.add(anim); mNeedToStart.add(anim); @@ -148,7 +149,7 @@ public class DrawableHolder implements AnimatorListener { */ public void startAnimations(ValueAnimator.AnimatorUpdateListener listener) { for (int i = 0; i < mNeedToStart.size(); i++) { - ObjectAnimator anim = mNeedToStart.get(i); + ObjectAnimator anim = mNeedToStart.get(i); anim.addUpdateListener(listener); anim.addListener(this); anim.start();