summaryrefslogtreecommitdiffstats
path: root/core/java
diff options
context:
space:
mode:
authorChet Haase <chet@google.com>2010-10-12 16:29:28 -0700
committerChet Haase <chet@google.com>2010-10-14 13:13:34 -0700
commit2794eb3b02e2404d453d3ad22a8a85a138130a07 (patch)
tree91fa1c08761921ce2976696234011c8d7f609161 /core/java
parentbf5b247fa120b3f8ee0331d00be25b1cf74dd3f3 (diff)
downloadframeworks_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.java2
-rw-r--r--core/java/android/animation/AnimatorInflater.java120
-rw-r--r--core/java/android/animation/AnimatorSet.java10
-rw-r--r--core/java/android/animation/KeyframeSet.java80
-rw-r--r--core/java/android/animation/LayoutTransition.java19
-rw-r--r--core/java/android/animation/ObjectAnimator.java197
-rw-r--r--core/java/android/animation/PropertyValuesHolder.java242
-rwxr-xr-xcore/java/android/animation/ValueAnimator.java297
-rw-r--r--core/java/android/widget/AdapterViewAnimator.java36
-rw-r--r--core/java/android/widget/StackView.java57
-rw-r--r--core/java/com/android/internal/widget/DrawableHolder.java19
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();