diff options
author | Chet Haase <chet@google.com> | 2010-10-12 16:29:28 -0700 |
---|---|---|
committer | Chet Haase <chet@google.com> | 2010-10-14 13:13:34 -0700 |
commit | 2794eb3b02e2404d453d3ad22a8a85a138130a07 (patch) | |
tree | 91fa1c08761921ce2976696234011c8d7f609161 /core/java | |
parent | bf5b247fa120b3f8ee0331d00be25b1cf74dd3f3 (diff) | |
download | frameworks_base-2794eb3b02e2404d453d3ad22a8a85a138130a07.zip frameworks_base-2794eb3b02e2404d453d3ad22a8a85a138130a07.tar.gz frameworks_base-2794eb3b02e2404d453d3ad22a8a85a138130a07.tar.bz2 |
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: Ib59a7dd72a95d438022e409ddeac48853082b943
Diffstat (limited to 'core/java')
-rw-r--r-- | core/java/android/animation/Animator.java | 2 | ||||
-rw-r--r-- | core/java/android/animation/AnimatorInflater.java | 120 | ||||
-rw-r--r-- | core/java/android/animation/AnimatorSet.java | 10 | ||||
-rw-r--r-- | core/java/android/animation/KeyframeSet.java | 80 | ||||
-rw-r--r-- | core/java/android/animation/LayoutTransition.java | 19 | ||||
-rw-r--r-- | core/java/android/animation/ObjectAnimator.java | 197 | ||||
-rw-r--r-- | core/java/android/animation/PropertyValuesHolder.java | 242 | ||||
-rwxr-xr-x | core/java/android/animation/ValueAnimator.java | 297 | ||||
-rw-r--r-- | core/java/android/widget/AdapterViewAnimator.java | 36 | ||||
-rw-r--r-- | core/java/android/widget/StackView.java | 57 | ||||
-rw-r--r-- | core/java/com/android/internal/widget/DrawableHolder.java | 19 |
11 files changed, 859 insertions, 220 deletions
diff --git a/core/java/android/animation/Animator.java b/core/java/android/animation/Animator.java index d3e0797..22e04a7 100644 --- a/core/java/android/animation/Animator.java +++ b/core/java/android/animation/Animator.java @@ -78,7 +78,7 @@ public abstract class Animator implements Cloneable { * * @param duration The length of the animation, in milliseconds. */ - public abstract void setDuration(long duration); + public abstract Animator setDuration(long duration); /** * Gets the length of the animation. diff --git a/core/java/android/animation/AnimatorInflater.java b/core/java/android/animation/AnimatorInflater.java index 0016459..4a6c460 100644 --- a/core/java/android/animation/AnimatorInflater.java +++ b/core/java/android/animation/AnimatorInflater.java @@ -52,8 +52,9 @@ public class AnimatorInflater { private static final int VALUE_TYPE_FLOAT = 0; private static final int VALUE_TYPE_INT = 1; private static final int VALUE_TYPE_DOUBLE = 2; - private static final int VALUE_TYPE_COLOR = 3; - private static final int VALUE_TYPE_CUSTOM = 4; + private static final int VALUE_TYPE_LONG = 3; + private static final int VALUE_TYPE_COLOR = 4; + private static final int VALUE_TYPE_CUSTOM = 5; /** * Loads an {@link Animator} object from a resource @@ -192,56 +193,113 @@ public class AnimatorInflater { int valueType = a.getInt(com.android.internal.R.styleable.Animator_valueType, VALUE_TYPE_FLOAT); - Object valueFrom = null; - Object valueTo = null; + if (anim == null) { + anim = new ValueAnimator(); + } TypeEvaluator evaluator = null; + boolean hasFrom = a.hasValue(com.android.internal.R.styleable.Animator_valueFrom); + boolean hasTo = a.hasValue(com.android.internal.R.styleable.Animator_valueTo); switch (valueType) { - case VALUE_TYPE_FLOAT: - if (a.hasValue(com.android.internal.R.styleable.Animator_valueFrom)) { + + case VALUE_TYPE_FLOAT: { + float valueFrom; + float valueTo; + if (hasFrom) { valueFrom = a.getFloat(com.android.internal.R.styleable.Animator_valueFrom, 0f); - } - if (a.hasValue(com.android.internal.R.styleable.Animator_valueTo)) { + if (hasTo) { + valueTo = a.getFloat(com.android.internal.R.styleable.Animator_valueTo, 0f); + anim.setFloatValues(valueFrom, valueTo); + } else { + anim.setFloatValues(valueFrom); + } + } else { valueTo = a.getFloat(com.android.internal.R.styleable.Animator_valueTo, 0f); + anim.setFloatValues(valueTo); } - break; + } + break; + case VALUE_TYPE_COLOR: evaluator = new RGBEvaluator(); + anim.setEvaluator(evaluator); // fall through to pick up values - case VALUE_TYPE_INT: - if (a.hasValue(com.android.internal.R.styleable.Animator_valueFrom)) { + case VALUE_TYPE_INT: { + int valueFrom; + int valueTo; + if (hasFrom) { valueFrom = a.getInteger(com.android.internal.R.styleable.Animator_valueFrom, 0); - } - if (a.hasValue(com.android.internal.R.styleable.Animator_valueTo)) { + if (hasTo) { + valueTo = a.getInteger(com.android.internal.R.styleable.Animator_valueTo, 0); + anim.setIntValues(valueFrom, valueTo); + } else { + anim.setIntValues(valueFrom); + } + } else { valueTo = a.getInteger(com.android.internal.R.styleable.Animator_valueTo, 0); + anim.setIntValues(valueTo); } - break; - case VALUE_TYPE_DOUBLE: - if (a.hasValue(com.android.internal.R.styleable.Animator_valueFrom)) { - valueFrom = (Double)((Float)(a.getFloat(com.android.internal.R.styleable.Animator_valueFrom, 0f))).doubleValue(); + } + break; + + case VALUE_TYPE_LONG: { + int valueFrom; + int valueTo; + if (hasFrom) { + valueFrom = a.getInteger(com.android.internal.R.styleable.Animator_valueFrom, 0); + if (hasTo) { + valueTo = a.getInteger(com.android.internal.R.styleable.Animator_valueTo, 0); + anim.setLongValues(valueFrom, valueTo); + } else { + anim.setLongValues(valueFrom); + } + } else { + valueTo = a.getInteger(com.android.internal.R.styleable.Animator_valueTo, 0); + anim.setLongValues(valueTo); } - if (a.hasValue(com.android.internal.R.styleable.Animator_valueTo)) { - valueTo = (Double)((Float)a.getFloat(com.android.internal.R.styleable.Animator_valueTo, 0f)).doubleValue(); + } + break; + + case VALUE_TYPE_DOUBLE: { + double valueFrom; + double valueTo; + if (hasFrom) { + valueFrom = a.getFloat(com.android.internal.R.styleable.Animator_valueFrom, 0f); + if (hasTo) { + valueTo = a.getFloat(com.android.internal.R.styleable.Animator_valueTo, 0f); + anim.setDoubleValues(valueFrom, valueTo); + } else { + anim.setDoubleValues(valueFrom); + } + } else { + valueTo = a.getFloat(com.android.internal.R.styleable.Animator_valueTo, 0f); + anim.setDoubleValues(valueTo); } - break; - case VALUE_TYPE_CUSTOM: + } + break; + + case VALUE_TYPE_CUSTOM: { // TODO: How to get an 'Object' value? - if (a.hasValue(com.android.internal.R.styleable.Animator_valueFrom)) { + float valueFrom; + float valueTo; + if (hasFrom) { valueFrom = a.getFloat(com.android.internal.R.styleable.Animator_valueFrom, 0f); - } - if (a.hasValue(com.android.internal.R.styleable.Animator_valueTo)) { + if (hasTo) { + valueTo = a.getFloat(com.android.internal.R.styleable.Animator_valueTo, 0f); + anim.setFloatValues(valueFrom, valueTo); + } else { + anim.setFloatValues(valueFrom); + } + } else { valueTo = a.getFloat(com.android.internal.R.styleable.Animator_valueTo, 0f); + anim.setFloatValues(valueTo); } - break; + } + break; } - if (anim == null) { - anim = new ValueAnimator(duration, valueFrom, valueTo); - } else { - anim.setDuration(duration); - anim.setValues(valueFrom, valueTo); - } + anim.setDuration(duration); anim.setStartDelay(startDelay); if (a.hasValue(com.android.internal.R.styleable.Animator_repeatCount)) { diff --git a/core/java/android/animation/AnimatorSet.java b/core/java/android/animation/AnimatorSet.java index 5de0293..8fc45f4 100644 --- a/core/java/android/animation/AnimatorSet.java +++ b/core/java/android/animation/AnimatorSet.java @@ -328,7 +328,7 @@ public final class AnimatorSet extends Animator { * animations of this AnimatorSet. */ @Override - public void setDuration(long duration) { + public AnimatorSet setDuration(long duration) { if (duration < 0) { throw new IllegalArgumentException("duration must be a value of zero or greater"); } @@ -338,6 +338,7 @@ public final class AnimatorSet extends Animator { node.animation.setDuration(duration); } mDuration = duration; + return this; } /** @@ -384,7 +385,8 @@ public final class AnimatorSet extends Animator { } } else { // TODO: Need to cancel out of the delay appropriately - ValueAnimator delayAnim = new ValueAnimator(mStartDelay, 0f, 1f); + ValueAnimator delayAnim = ValueAnimator.ofFloat(0f, 1f); + delayAnim.setDuration(mStartDelay); delayAnim.addListener(new AnimatorListenerAdapter() { public void onAnimationEnd(Animator anim) { for (Node node : nodesToStart) { @@ -929,7 +931,9 @@ public final class AnimatorSet extends Animator { */ public void after(long delay) { // setup dummy ValueAnimator just to run the clock - after(new ValueAnimator(delay, 0f, 1f)); + ValueAnimator anim = ValueAnimator.ofFloat(0f, 1f); + anim.setDuration(delay); + after(anim); } } diff --git a/core/java/android/animation/KeyframeSet.java b/core/java/android/animation/KeyframeSet.java index a24b1fb..1741e60 100644 --- a/core/java/android/animation/KeyframeSet.java +++ b/core/java/android/animation/KeyframeSet.java @@ -17,6 +17,7 @@ package android.animation; import java.util.ArrayList; +import java.util.Arrays; /** * This class holds a collection of Keyframe objects and is called by ValueAnimator to calculate @@ -31,12 +32,85 @@ class KeyframeSet { public KeyframeSet(Keyframe... keyframes) { mKeyframes = new ArrayList<Keyframe>(); - 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 56ad857..d843737 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<Integer> pvhLeft = new PropertyValuesHolder<Integer>("left", 0, 1); - PropertyValuesHolder<Integer> pvhTop = new PropertyValuesHolder<Integer>("top", 0, 1); - PropertyValuesHolder<Integer> pvhRight = new PropertyValuesHolder<Integer>("right", 0, 1); - PropertyValuesHolder<Integer> pvhBottom = new PropertyValuesHolder<Integer>("bottom", 0, 1); - defaultChangeIn = new ObjectAnimator<PropertyValuesHolder>(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<Float>(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<Float>(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 31ddb0b..7427651 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<T> extends ValueAnimator<T> { +public final class ObjectAnimator extends ValueAnimator { // The target object on which the property exists, set in the constructor private Object mTarget; @@ -122,50 +122,200 @@ public final class ObjectAnimator<T> extends ValueAnimator<T> { * 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 <code>setName()</code>, where <code>name</code> is * the value of the <code>propertyName</code> 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 <code>setName()</code>, where <code>name</code> is + * the value of the <code>propertyName</code> 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 <code>setName()</code>, where <code>name</code> is + * the value of the <code>propertyName</code> 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 <code>setName()</code>, where <code>name</code> is + * the value of the <code>propertyName</code> 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 <code>setName()</code>, where <code>name</code> is + * the value of the <code>propertyName</code> 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 <code>PropertyValueHolder</code> 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 <code>setName()</code>, where <code>name</code> is * the name of the property passed in as the <code>propertyName</code> 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; + } + + /** + * Constructs and returns an ObjectAnimator that animates between the sets of values + * specifed in <code>PropertyValueHolder</code> 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 <code>setName()</code>, where <code>name</code> is + * the name of the property passed in as the <code>propertyName</code> 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.mTarget = target; + anim.setValues(values); + return anim; + } + + @Override + public void setIntValues(int... 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(PropertyValuesHolder.ofInt(mPropertyName, values)); + } else { + super.setIntValues(values); + } + } + + @Override + public void setFloatValues(float... 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(PropertyValuesHolder.ofFloat(mPropertyName, values)); + } else { + super.setFloatValues(values); + } + } + + @Override + public void setDoubleValues(double... 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(PropertyValuesHolder.ofDouble(mPropertyName, values)); + } else { + super.setDoubleValues(values); + } + } + + @Override + public void setLongValues(long... 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(PropertyValuesHolder.ofLong(mPropertyName, values)); + } else { + super.setLongValues(values); + } } @Override - public void setValues(T... values) { + public void setObjectValues(Object... 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)}); + setValues(PropertyValuesHolder.ofObject(mPropertyName, (TypeEvaluator)null, values)); } else { - super.setValues((T[]) values); + super.setObjectValues(values); } } @@ -194,6 +344,21 @@ public final class ObjectAnimator<T> extends ValueAnimator<T> { } } + /** + * 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 + * <code>ObjectAnimator.ofInt(target, propertyName, 0, 10).setDuration(500).start()</code>. + */ + @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 1d46123..da7c29b 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<T> 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,90 @@ public class PropertyValuesHolder<T> 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 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); + Log.v("PVH", "ofFloat: propertyName: " + pvh.mPropertyName); + 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); + Log.v("PVH", "ofFloat: propertyName: " + pvh.mPropertyName); + 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 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 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. * <p>If there is only one value, it is assumed to be the end value of an animation, @@ -151,13 +219,14 @@ public class PropertyValuesHolder<T> 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; } /** - * Sets the values being animated between. + * 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 @@ -167,51 +236,104 @@ public class PropertyValuesHolder<T> implements Cloneable { * derived automatically from <code>propertyName</code> 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 The set of values to animate between. + * + * @param values One or more values that the animation will animate between. */ - public void setValues(T... values) { + 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 <code>propertyName</code> 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 <code>propertyName</code> 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 <code>propertyName</code> 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; - for (int i = 0; i < numKeyframes; ++i) { - if (values[i] != null) { - Class thisValueType = values[i].getClass(); - if (mValueType == null) { - mValueType = thisValueType; - } else { - if (thisValueType != mValueType) { - if (mValueType == Integer.class && - (thisValueType == Float.class || thisValueType == Double.class)) { - mValueType = thisValueType; - } else if (mValueType == Float.class && thisValueType == Double.class) { - mValueType = thisValueType; - } - } - } - } - } Keyframe keyframes[] = new Keyframe[Math.max(numKeyframes,2)]; - if (mValueType.equals(Keyframe.class)) { - mValueType = ((Keyframe)values[0]).getType(); - for (int i = 0; i < numKeyframes; ++i) { - keyframes[i] = (Keyframe)values[i]; - } - } else { - 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) { - if (values[i] != null && (values[i].getClass() != mValueType)) { - - } - keyframes[i] = new Keyframe((float) i / (numKeyframes - 1), values[i]); - } - } + 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 <code>propertyName</code> 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); + } /** * Determine the setter or getter function using the JavaBeans convention of setFoo or @@ -230,6 +352,8 @@ public class PropertyValuesHolder<T> implements Cloneable { */ private Method getPropertyFunction(Class targetClass, String prefix, Class valueType) { // TODO: faster implementation... + Log.v("PVH", "getPropertyFunction: class, prefix, valueType, propertyName: " + + targetClass + ", " + prefix + ", " + valueType + ", "+ mPropertyName); Method returnVal = null; String firstLetter = mPropertyName.substring(0, 1); String theRest = mPropertyName.substring(1); @@ -351,7 +475,7 @@ public class PropertyValuesHolder<T> 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 +498,7 @@ public class PropertyValuesHolder<T> 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 +538,7 @@ public class PropertyValuesHolder<T> 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 a6f061d..8aa2995 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)}.</p> */ -public class ValueAnimator<T> extends Animator { +public class ValueAnimator extends Animator { /** * Internal constants @@ -154,7 +154,7 @@ public class ValueAnimator<T> 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<T> 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. + * + * <p>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. + * + * <p>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.</p> + * + * @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. + * + * <p>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.</p> + * + * @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. + * + * <p>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.</p> + * + * @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. + * + * <p>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.</p> + * + * @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. + * + * <p>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.</p> + * + * <p>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.</p> + * + * @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; } /** @@ -275,30 +508,6 @@ public class ValueAnimator<T> extends Animator { } /** - * Sets the values to animate between for this animation. If <code>values</code> 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 <code>startDelay</code>, the * function is called after that delay ends. @@ -321,16 +530,20 @@ public class ValueAnimator<T> 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 <code>ValueAnimator.ofInt(0, 10).setDuration(500).start()</code>. */ - 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 b7b1a23..b5934b0 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<Adapter> /** * In and out animations. */ - ObjectAnimator<?> mInAnimation; - ObjectAnimator<?> mOutAnimation; + ObjectAnimator mInAnimation; + ObjectAnimator mOutAnimation; private ArrayList<View> mViewsToBringToFront; @@ -246,12 +246,16 @@ public abstract class AdapterViewAnimator extends AdapterView<Adapter> } } - ObjectAnimator<?> getDefaultInAnimation() { - return new ObjectAnimator<Float>(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<Float>(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<Adapter> * * @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<Adapter> * @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<Adapter> * * @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<Adapter> * @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<Adapter> * @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<Adapter> * @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 f0954e2..7e01506 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<Float> fadeIn = new ObjectAnimator<Float>(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<Float> slideInY = - new PropertyValuesHolder<Float>("YProgress", 0.0f); - PropertyValuesHolder<Float> slideInX = - new PropertyValuesHolder<Float>("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<Float> slideOutY = - new PropertyValuesHolder<Float>("YProgress", 1.0f); - PropertyValuesHolder<Float> slideOutX = - new PropertyValuesHolder<Float>("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<Float> fadeOut = new ObjectAnimator<Float> - (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<Float> scaleX = new PropertyValuesHolder<Float>("scaleX", scale); - PropertyValuesHolder<Float> scaleY = new PropertyValuesHolder<Float>("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<Float> translationY = - new PropertyValuesHolder<Float>("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<Float> snapBackY = - new PropertyValuesHolder<Float>("YProgress", finalYProgress); - PropertyValuesHolder<Float> snapBackX = - new PropertyValuesHolder<Float>("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<Float> snapBackY = - new PropertyValuesHolder<Float>("YProgress", finalYProgress); - PropertyValuesHolder<Float> snapBackX = - new PropertyValuesHolder<Float>("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 d53860c..958cabb 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<ObjectAnimator<Float>> mAnimators = new ArrayList<ObjectAnimator<Float>>(); - private ArrayList<ObjectAnimator<Float>> mNeedToStart = new ArrayList<ObjectAnimator<Float>>(); + private ArrayList<ObjectAnimator> mAnimators = new ArrayList<ObjectAnimator>(); + private ArrayList<ObjectAnimator> mNeedToStart = new ArrayList<ObjectAnimator>(); 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<Float> addAnimTo(long duration, long delay, + public ObjectAnimator addAnimTo(long duration, long delay, String property, float toValue, boolean replace) { if (replace) removeAnimationFor(property); - ObjectAnimator<Float> anim = new ObjectAnimator<Float>(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<ObjectAnimator<Float>> removalList = new ArrayList<ObjectAnimator<Float>>(); - for (ObjectAnimator<Float> currentAnim : mAnimators) { + ArrayList<ObjectAnimator> removalList = new ArrayList<ObjectAnimator>(); + 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<Float> 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<Float> 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<Float> anim = mNeedToStart.get(i); + ObjectAnimator anim = mNeedToStart.get(i); anim.addUpdateListener(listener); anim.addListener(this); anim.start(); |