Merge "Support for multiple value animations."
diff --git a/api/current.txt b/api/current.txt
index 7744752..ac42ce1 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -2442,11 +2442,23 @@
method public java.lang.Object evaluate(float, java.lang.Object, java.lang.Object);
}
+ public class FloatArrayEvaluator implements android.animation.TypeEvaluator {
+ ctor public FloatArrayEvaluator();
+ ctor public FloatArrayEvaluator(float[]);
+ method public float[] evaluate(float, float[], float[]);
+ }
+
public class FloatEvaluator implements android.animation.TypeEvaluator {
ctor public FloatEvaluator();
method public java.lang.Float evaluate(float, java.lang.Number, java.lang.Number);
}
+ public class IntArrayEvaluator implements android.animation.TypeEvaluator {
+ ctor public IntArrayEvaluator();
+ ctor public IntArrayEvaluator(int[]);
+ method public int[] evaluate(float, int[], int[]);
+ }
+
public class IntEvaluator implements android.animation.TypeEvaluator {
ctor public IntEvaluator();
method public java.lang.Integer evaluate(float, java.lang.Integer, java.lang.Integer);
@@ -2519,6 +2531,10 @@
method public static android.animation.ObjectAnimator ofFloat(T, android.util.Property<T, java.lang.Float>, float...);
method public static android.animation.ObjectAnimator ofInt(java.lang.Object, java.lang.String, int...);
method public static android.animation.ObjectAnimator ofInt(T, android.util.Property<T, java.lang.Integer>, int...);
+ method public static android.animation.ObjectAnimator ofMultiFloat(java.lang.Object, java.lang.String, float[][]);
+ method public static android.animation.ObjectAnimator ofMultiFloat(java.lang.Object, java.lang.String, android.animation.TypeConverter<T, float[]>, android.animation.TypeEvaluator<T>, T...);
+ method public static android.animation.ObjectAnimator ofMultiInt(java.lang.Object, java.lang.String, int[][]);
+ method public static android.animation.ObjectAnimator ofMultiInt(java.lang.Object, java.lang.String, android.animation.TypeConverter<T, int[]>, android.animation.TypeEvaluator<T>, T...);
method public static android.animation.ObjectAnimator ofObject(java.lang.Object, java.lang.String, android.animation.TypeEvaluator, java.lang.Object...);
method public static android.animation.ObjectAnimator ofObject(T, android.util.Property<T, V>, android.animation.TypeEvaluator<V>, V...);
method public static android.animation.ObjectAnimator ofObject(T, android.util.Property<T, P>, android.animation.TypeConverter<V, P>, android.animation.TypeEvaluator<V>, V...);
@@ -2537,6 +2553,12 @@
method public static android.animation.PropertyValuesHolder ofInt(android.util.Property<?, java.lang.Integer>, int...);
method public static android.animation.PropertyValuesHolder ofKeyframe(java.lang.String, android.animation.Keyframe...);
method public static android.animation.PropertyValuesHolder ofKeyframe(android.util.Property, android.animation.Keyframe...);
+ method public static android.animation.PropertyValuesHolder ofMultiFloat(java.lang.String, float[][]);
+ method public static android.animation.PropertyValuesHolder ofMultiFloat(java.lang.String, android.animation.TypeConverter<V, float[]>, android.animation.TypeEvaluator<V>, V...);
+ method public static android.animation.PropertyValuesHolder ofMultiFloat(java.lang.String, android.animation.TypeConverter<T, float[]>, android.animation.TypeEvaluator<T>, android.animation.Keyframe...);
+ method public static android.animation.PropertyValuesHolder ofMultiInt(java.lang.String, int[][]);
+ method public static android.animation.PropertyValuesHolder ofMultiInt(java.lang.String, android.animation.TypeConverter<V, int[]>, android.animation.TypeEvaluator<V>, V...);
+ method public static android.animation.PropertyValuesHolder ofMultiInt(java.lang.String, android.animation.TypeConverter<T, int[]>, android.animation.TypeEvaluator<T>, android.animation.Keyframe...);
method public static android.animation.PropertyValuesHolder ofObject(java.lang.String, android.animation.TypeEvaluator, java.lang.Object...);
method public static android.animation.PropertyValuesHolder ofObject(android.util.Property, android.animation.TypeEvaluator<V>, V...);
method public static android.animation.PropertyValuesHolder ofObject(android.util.Property<?, V>, android.animation.TypeConverter<T, V>, android.animation.TypeEvaluator<T>, T...);
diff --git a/core/java/android/animation/FloatArrayEvaluator.java b/core/java/android/animation/FloatArrayEvaluator.java
new file mode 100644
index 0000000..9ae1197
--- /dev/null
+++ b/core/java/android/animation/FloatArrayEvaluator.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.animation;
+
+/**
+ * This evaluator can be used to perform type interpolation between <code>float[]</code> values.
+ * Each index into the array is treated as a separate value to interpolate. For example,
+ * evaluating <code>{100, 200}</code> and <code>{300, 400}</code> will interpolate the value at
+ * the first index between 100 and 300 and the value at the second index value between 200 and 400.
+ */
+public class FloatArrayEvaluator implements TypeEvaluator<float[]> {
+
+ private float[] mArray;
+
+ /**
+ * Create a FloatArrayEvaluator that does not reuse the animated value. Care must be taken
+ * when using this option because on every evaluation a new <code>float[]</code> will be
+ * allocated.
+ *
+ * @see #FloatArrayEvaluator(float[])
+ */
+ public FloatArrayEvaluator() {
+ }
+
+ /**
+ * Create a FloatArrayEvaluator that reuses <code>reuseArray</code> for every evaluate() call.
+ * Caution must be taken to ensure that the value returned from
+ * {@link android.animation.ValueAnimator#getAnimatedValue()} is not cached, modified, or
+ * used across threads. The value will be modified on each <code>evaluate()</code> call.
+ *
+ * @param reuseArray The array to modify and return from <code>evaluate</code>.
+ */
+ public FloatArrayEvaluator(float[] reuseArray) {
+ mArray = reuseArray;
+ }
+
+ /**
+ * Interpolates the value at each index by the fraction. If
+ * {@link #FloatArrayEvaluator(float[])} was used to construct this object,
+ * <code>reuseArray</code> will be returned, otherwise a new <code>float[]</code>
+ * will be returned.
+ *
+ * @param fraction The fraction from the starting to the ending values
+ * @param startValue The start value.
+ * @param endValue The end value.
+ * @return A <code>float[]</code> where each element is an interpolation between
+ * the same index in startValue and endValue.
+ */
+ @Override
+ public float[] evaluate(float fraction, float[] startValue, float[] endValue) {
+ float[] array = mArray;
+ if (array == null) {
+ array = new float[startValue.length];
+ }
+
+ for (int i = 0; i < array.length; i++) {
+ float start = startValue[i];
+ float end = endValue[i];
+ array[i] = start + (fraction * (end - start));
+ }
+ return array;
+ }
+}
diff --git a/core/java/android/animation/IntArrayEvaluator.java b/core/java/android/animation/IntArrayEvaluator.java
new file mode 100644
index 0000000..d7f10f3
--- /dev/null
+++ b/core/java/android/animation/IntArrayEvaluator.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.animation;
+
+/**
+ * This evaluator can be used to perform type interpolation between <code>int[]</code> values.
+ * Each index into the array is treated as a separate value to interpolate. For example,
+ * evaluating <code>{100, 200}</code> and <code>{300, 400}</code> will interpolate the value at
+ * the first index between 100 and 300 and the value at the second index value between 200 and 400.
+ */
+public class IntArrayEvaluator implements TypeEvaluator<int[]> {
+
+ private int[] mArray;
+
+ /**
+ * Create an IntArrayEvaluator that does not reuse the animated value. Care must be taken
+ * when using this option because on every evaluation a new <code>int[]</code> will be
+ * allocated.
+ *
+ * @see #IntArrayEvaluator(int[])
+ */
+ public IntArrayEvaluator() {
+ }
+
+ /**
+ * Create an IntArrayEvaluator that reuses <code>reuseArray</code> for every evaluate() call.
+ * Caution must be taken to ensure that the value returned from
+ * {@link android.animation.ValueAnimator#getAnimatedValue()} is not cached, modified, or
+ * used across threads. The value will be modified on each <code>evaluate()</code> call.
+ *
+ * @param reuseArray The array to modify and return from <code>evaluate</code>.
+ */
+ public IntArrayEvaluator(int[] reuseArray) {
+ mArray = reuseArray;
+ }
+
+ /**
+ * Interpolates the value at each index by the fraction. If {@link #IntArrayEvaluator(int[])}
+ * was used to construct this object, <code>reuseArray</code> will be returned, otherwise
+ * a new <code>int[]</code> will be returned.
+ *
+ * @param fraction The fraction from the starting to the ending values
+ * @param startValue The start value.
+ * @param endValue The end value.
+ * @return An <code>int[]</code> where each element is an interpolation between
+ * the same index in startValue and endValue.
+ */
+ @Override
+ public int[] evaluate(float fraction, int[] startValue, int[] endValue) {
+ int[] array = mArray;
+ if (array == null) {
+ array = new int[startValue.length];
+ }
+ for (int i = 0; i < array.length; i++) {
+ int start = startValue[i];
+ int end = endValue[i];
+ array[i] = (int) (start + (fraction * (end - start)));
+ }
+ return array;
+ }
+}
diff --git a/core/java/android/animation/ObjectAnimator.java b/core/java/android/animation/ObjectAnimator.java
index f930f22..07a2821 100644
--- a/core/java/android/animation/ObjectAnimator.java
+++ b/core/java/android/animation/ObjectAnimator.java
@@ -228,6 +228,53 @@
}
/**
+ * Constructs and returns an ObjectAnimator that animates over int values for a multiple
+ * parameters setter. Only public methods that take only int parameters are supported.
+ * Each <code>int[]</code> contains a complete set of parameters to the setter method.
+ * At least two <code>int[]</code> values must be provided, a start and end. More than two
+ * values imply a starting value, values to animate through along the way, and an ending
+ * value (these values will be distributed evenly across the duration of the animation).
+ *
+ * @param target The object whose property is to be animated. This object may
+ * have a public method on it called <code>setName()</code>, where <code>name</code> is
+ * the value of the <code>propertyName</code> parameter. <code>propertyName</code> may also
+ * be the case-sensitive complete name of the public setter method.
+ * @param propertyName The name of the property being animated or the name of the setter method.
+ * @param values A set of values that the animation will animate between over time.
+ * @return An ObjectAnimator object that is set up to animate between the given values.
+ */
+ public static ObjectAnimator ofMultiInt(Object target, String propertyName, int[][] values) {
+ PropertyValuesHolder pvh = PropertyValuesHolder.ofMultiInt(propertyName, values);
+ return ofPropertyValuesHolder(target, pvh);
+ }
+
+ /**
+ * Constructs and returns an ObjectAnimator that animates over values for a multiple int
+ * parameters setter. Only public methods that take only int parameters are supported.
+ * <p>At least two values must be provided, a start and end. More than two
+ * values imply a starting value, values to animate through along the way, and an ending
+ * value (these values will be distributed evenly across the duration of the animation).</p>
+ *
+ * @param target The object whose property is to be animated. This object may
+ * have a public method on it called <code>setName()</code>, where <code>name</code> is
+ * the value of the <code>propertyName</code> parameter. <code>propertyName</code> may also
+ * be the complete name of the public method.
+ * @param propertyName The name of the property being animated or the name of the setter method.
+ * @param converter Converts T objects into int parameters for the multi-value setter.
+ * @param evaluator A TypeEvaluator that will be called on each animation frame to
+ * provide the necessary interpolation between the Object values to derive the animated
+ * value.
+ * @param values A set of values that the animation will animate between over time.
+ * @return An ObjectAnimator object that is set up to animate between the given values.
+ */
+ public static <T> ObjectAnimator ofMultiInt(Object target, String propertyName,
+ TypeConverter<T, int[]> converter, TypeEvaluator<T> evaluator, T... values) {
+ PropertyValuesHolder pvh = PropertyValuesHolder.ofMultiInt(propertyName, converter,
+ evaluator, values);
+ return ObjectAnimator.ofPropertyValuesHolder(target, pvh);
+ }
+
+ /**
* Constructs and returns an ObjectAnimator that animates between float values. A single
* value implies that that value is the one being animated to. Two values imply starting
* and ending values. More than two values imply a starting value, values to animate through
@@ -267,6 +314,54 @@
}
/**
+ * Constructs and returns an ObjectAnimator that animates over float values for a multiple
+ * parameters setter. Only public methods that take only float parameters are supported.
+ * Each <code>float[]</code> contains a complete set of parameters to the setter method.
+ * At least two <code>float[]</code> values must be provided, a start and end. More than two
+ * values imply a starting value, values to animate through along the way, and an ending
+ * value (these values will be distributed evenly across the duration of the animation).
+ *
+ * @param target The object whose property is to be animated. This object may
+ * have a public method on it called <code>setName()</code>, where <code>name</code> is
+ * the value of the <code>propertyName</code> parameter. <code>propertyName</code> may also
+ * be the complete name of the public method.
+ * @param propertyName The name of the property being animated or the name of the setter method.
+ * @param values A set of values that the animation will animate between over time.
+ * @return An ObjectAnimator object that is set up to animate between the given values.
+ */
+ public static ObjectAnimator ofMultiFloat(Object target, String propertyName,
+ float[][] values) {
+ PropertyValuesHolder pvh = PropertyValuesHolder.ofMultiFloat(propertyName, values);
+ return ofPropertyValuesHolder(target, pvh);
+ }
+
+ /**
+ * Constructs and returns an ObjectAnimator that animates over values for a multiple float
+ * parameters setter. Only public methods that take only float parameters are supported.
+ * <p>At least two values must be provided, a start and end. More than two
+ * values imply a starting value, values to animate through along the way, and an ending
+ * value (these values will be distributed evenly across the duration of the animation).</p>
+ *
+ * @param target The object whose property is to be animated. This object may
+ * have a public method on it called <code>setName()</code>, where <code>name</code> is
+ * the value of the <code>propertyName</code> parameter. <code>propertyName</code> may also
+ * be the case-sensitive complete name of the public setter method.
+ * @param propertyName The name of the property being animated or the name of the setter method.
+ * @param converter Converts T objects into float parameters for the multi-value setter.
+ * @param evaluator A TypeEvaluator that will be called on each animation frame to
+ * provide the necessary interpolation between the Object values to derive the animated
+ * value.
+ * @param values A set of values that the animation will animate between over time.
+ * @return An ObjectAnimator object that is set up to animate between the given values.
+ */
+ public static <T> ObjectAnimator ofMultiFloat(Object target, String propertyName,
+ TypeConverter<T, float[]> converter, TypeEvaluator<T> evaluator, T... values) {
+ PropertyValuesHolder pvh = PropertyValuesHolder.ofMultiFloat(propertyName, converter,
+ evaluator, values);
+ return ObjectAnimator.ofPropertyValuesHolder(target, pvh);
+ }
+
+ /**
* Constructs and returns an ObjectAnimator that animates between Object values. A single
* value implies that that value is the one being animated to. Two values imply starting
* and ending values. More than two values imply a starting value, values to animate through
diff --git a/core/java/android/animation/PropertyValuesHolder.java b/core/java/android/animation/PropertyValuesHolder.java
index 5f5e485..c291970 100644
--- a/core/java/android/animation/PropertyValuesHolder.java
+++ b/core/java/android/animation/PropertyValuesHolder.java
@@ -171,6 +171,84 @@
/**
* Constructs and returns a PropertyValuesHolder with a given property name and
+ * set of <code>int[]</code> values. At least two <code>int[]</code> values must be supplied,
+ * a start and end value. If more values are supplied, the values will be animated from the
+ * start, through all intermediate values to the end value. When used with ObjectAnimator,
+ * the elements of the array represent the parameters of the setter function.
+ *
+ * @param propertyName The name of the property being animated. Can also be the name of the
+ * entire setter method. Should not be null.
+ * @param values The values that the property will animate between.
+ * @return PropertyValuesHolder The constructed PropertyValuesHolder object.
+ * @see IntArrayEvaluator#IntArrayEvaluator(int[])
+ * @see ObjectAnimator#ofMultiInt(Object, String, TypeConverter, TypeEvaluator, Object[])
+ */
+ public static PropertyValuesHolder ofMultiInt(String propertyName, int[][] values) {
+ if (values.length < 2) {
+ throw new IllegalArgumentException("At least 2 values must be supplied");
+ }
+ int numParameters = 0;
+ for (int i = 0; i < values.length; i++) {
+ if (values[i] == null) {
+ throw new IllegalArgumentException("values must not be null");
+ }
+ int length = values[i].length;
+ if (i == 0) {
+ numParameters = length;
+ } else if (length != numParameters) {
+ throw new IllegalArgumentException("Values must all have the same length");
+ }
+ }
+ IntArrayEvaluator evaluator = new IntArrayEvaluator(new int[numParameters]);
+ return new MultiIntValuesHolder(propertyName, null, evaluator, (Object[]) values);
+ }
+
+ /**
+ * Constructs and returns a PropertyValuesHolder with a given property and
+ * set of Object values for use with ObjectAnimator multi-value setters. The Object
+ * values are converted to <code>int[]</code> using the converter.
+ *
+ * @param propertyName The property being animated or complete name of the setter.
+ * Should not be null.
+ * @param converter Used to convert the animated value to setter parameters.
+ * @param evaluator A TypeEvaluator that will be called on each animation frame to
+ * provide the necessary interpolation between the Object values to derive the animated
+ * value.
+ * @param values The values that the property will animate between.
+ * @return PropertyValuesHolder The constructed PropertyValuesHolder object.
+ * @see ObjectAnimator#ofMultiInt(Object, String, TypeConverter, TypeEvaluator, Object[])
+ * @see ObjectAnimator#ofPropertyValuesHolder(Object, PropertyValuesHolder...)
+ */
+ public static <V> PropertyValuesHolder ofMultiInt(String propertyName,
+ TypeConverter<V, int[]> converter, TypeEvaluator<V> evaluator, V... values) {
+ return new MultiIntValuesHolder(propertyName, converter, evaluator, values);
+ }
+
+ /**
+ * Constructs and returns a PropertyValuesHolder object with the specified property name or
+ * setter name for use in a multi-int setter function using ObjectAnimator. The values can be
+ * of any type, but the type should be consistent so that the supplied
+ * {@link android.animation.TypeEvaluator} can be used to to evaluate the animated value. The
+ * <code>converter</code> converts the values to parameters in the setter function.
+ *
+ * <p>At least two values must be supplied, a start and an end value.</p>
+ *
+ * @param propertyName The name of the property to associate with the set of values. This
+ * may also be the complete name of a setter function.
+ * @param converter Converts <code>values</code> into int parameters for the setter.
+ * Can be null if the Keyframes have int[] values.
+ * @param evaluator Used to interpolate between values.
+ * @param values The values at specific fractional times to evaluate between
+ * @return A PropertyValuesHolder for a multi-int parameter setter.
+ */
+ public static <T> PropertyValuesHolder ofMultiInt(String propertyName,
+ TypeConverter<T, int[]> converter, TypeEvaluator<T> evaluator, Keyframe... values) {
+ KeyframeSet keyframeSet = KeyframeSet.ofKeyframe(values);
+ return new MultiIntValuesHolder(propertyName, converter, evaluator, keyframeSet);
+ }
+
+ /**
+ * 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.
@@ -193,6 +271,83 @@
/**
* Constructs and returns a PropertyValuesHolder with a given property name and
+ * set of <code>float[]</code> values. At least two <code>float[]</code> values must be supplied,
+ * a start and end value. If more values are supplied, the values will be animated from the
+ * start, through all intermediate values to the end value. When used with ObjectAnimator,
+ * the elements of the array represent the parameters of the setter function.
+ *
+ * @param propertyName The name of the property being animated. Can also be the name of the
+ * entire setter method. Should not be null.
+ * @param values The values that the property will animate between.
+ * @return PropertyValuesHolder The constructed PropertyValuesHolder object.
+ * @see FloatArrayEvaluator#FloatArrayEvaluator(float[])
+ * @see ObjectAnimator#ofMultiFloat(Object, String, TypeConverter, TypeEvaluator, Object[])
+ */
+ public static PropertyValuesHolder ofMultiFloat(String propertyName, float[][] values) {
+ if (values.length < 2) {
+ throw new IllegalArgumentException("At least 2 values must be supplied");
+ }
+ int numParameters = 0;
+ for (int i = 0; i < values.length; i++) {
+ if (values[i] == null) {
+ throw new IllegalArgumentException("values must not be null");
+ }
+ int length = values[i].length;
+ if (i == 0) {
+ numParameters = length;
+ } else if (length != numParameters) {
+ throw new IllegalArgumentException("Values must all have the same length");
+ }
+ }
+ FloatArrayEvaluator evaluator = new FloatArrayEvaluator(new float[numParameters]);
+ return new MultiFloatValuesHolder(propertyName, null, evaluator, (Object[]) values);
+ }
+
+ /**
+ * Constructs and returns a PropertyValuesHolder with a given property and
+ * set of Object values for use with ObjectAnimator multi-value setters. The Object
+ * values are converted to <code>float[]</code> using the converter.
+ *
+ * @param propertyName The property being animated or complete name of the setter.
+ * Should not be null.
+ * @param converter Used to convert the animated value to setter parameters.
+ * @param evaluator A TypeEvaluator that will be called on each animation frame to
+ * provide the necessary interpolation between the Object values to derive the animated
+ * value.
+ * @param values The values that the property will animate between.
+ * @return PropertyValuesHolder The constructed PropertyValuesHolder object.
+ * @see ObjectAnimator#ofMultiFloat(Object, String, TypeConverter, TypeEvaluator, Object[])
+ */
+ public static <V> PropertyValuesHolder ofMultiFloat(String propertyName,
+ TypeConverter<V, float[]> converter, TypeEvaluator<V> evaluator, V... values) {
+ return new MultiFloatValuesHolder(propertyName, converter, evaluator, values);
+ }
+
+ /**
+ * Constructs and returns a PropertyValuesHolder object with the specified property name or
+ * setter name for use in a multi-float setter function using ObjectAnimator. The values can be
+ * of any type, but the type should be consistent so that the supplied
+ * {@link android.animation.TypeEvaluator} can be used to to evaluate the animated value. The
+ * <code>converter</code> converts the values to parameters in the setter function.
+ *
+ * <p>At least two values must be supplied, a start and an end value.</p>
+ *
+ * @param propertyName The name of the property to associate with the set of values. This
+ * may also be the complete name of a setter function.
+ * @param converter Converts <code>values</code> into float parameters for the setter.
+ * Can be null if the Keyframes have float[] values.
+ * @param evaluator Used to interpolate between values.
+ * @param values The values at specific fractional times to evaluate between
+ * @return A PropertyValuesHolder for a multi-float parameter setter.
+ */
+ public static <T> PropertyValuesHolder ofMultiFloat(String propertyName,
+ TypeConverter<T, float[]> converter, TypeEvaluator<T> evaluator, Keyframe... values) {
+ KeyframeSet keyframeSet = KeyframeSet.ofKeyframe(values);
+ return new MultiFloatValuesHolder(propertyName, converter, evaluator, keyframeSet);
+ }
+
+ /**
+ * 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 automatically interpolate between objects of unknown type.
*
@@ -1078,8 +1233,227 @@
}
+ static class MultiFloatValuesHolder extends PropertyValuesHolder {
+ private int mJniSetter;
+ private static final HashMap<Class, HashMap<String, Integer>> sJNISetterPropertyMap =
+ new HashMap<Class, HashMap<String, Integer>>();
+
+ public MultiFloatValuesHolder(String propertyName, TypeConverter converter,
+ TypeEvaluator evaluator, Object... values) {
+ super(propertyName);
+ setConverter(converter);
+ setObjectValues(values);
+ setEvaluator(evaluator);
+ }
+
+ public MultiFloatValuesHolder(String propertyName, TypeConverter converter,
+ TypeEvaluator evaluator, KeyframeSet keyframeSet) {
+ super(propertyName);
+ setConverter(converter);
+ mKeyframeSet = keyframeSet;
+ setEvaluator(evaluator);
+ }
+
+ /**
+ * Internal function to set the value on the target object, using the setter set up
+ * earlier on this PropertyValuesHolder object. This function is called by ObjectAnimator
+ * to handle turning the value calculated by ValueAnimator into a value set on the object
+ * according to the name of the property.
+ *
+ * @param target The target object on which the value is set
+ */
+ @Override
+ void setAnimatedValue(Object target) {
+ float[] values = (float[]) getAnimatedValue();
+ int numParameters = values.length;
+ if (mJniSetter != 0) {
+ switch (numParameters) {
+ case 1:
+ nCallFloatMethod(target, mJniSetter, values[0]);
+ break;
+ case 2:
+ nCallTwoFloatMethod(target, mJniSetter, values[0], values[1]);
+ break;
+ case 4:
+ nCallFourFloatMethod(target, mJniSetter, values[0], values[1],
+ values[2], values[3]);
+ break;
+ default: {
+ nCallMultipleFloatMethod(target, mJniSetter, values);
+ break;
+ }
+ }
+ }
+ }
+
+ /**
+ * Internal function (called from ObjectAnimator) to set up the setter and getter
+ * prior to running the animation. No getter can be used for multiple parameters.
+ *
+ * @param target The object on which the setter exists.
+ */
+ @Override
+ void setupSetterAndGetter(Object target) {
+ setupSetter(target.getClass());
+ }
+
+ @Override
+ void setupSetter(Class targetClass) {
+ if (mJniSetter != 0) {
+ return;
+ }
+ try {
+ mPropertyMapLock.writeLock().lock();
+ HashMap<String, Integer> propertyMap = sJNISetterPropertyMap.get(targetClass);
+ if (propertyMap != null) {
+ Integer jniSetterInteger = propertyMap.get(mPropertyName);
+ if (jniSetterInteger != null) {
+ mJniSetter = jniSetterInteger;
+ }
+ }
+ if (mJniSetter == 0) {
+ String methodName = getMethodName("set", mPropertyName);
+ calculateValue(0f);
+ float[] values = (float[]) getAnimatedValue();
+ int numParams = values.length;
+ try {
+ mJniSetter = nGetMultipleFloatMethod(targetClass, methodName, numParams);
+ } catch (NoSuchMethodError e) {
+ // try without the 'set' prefix
+ mJniSetter = nGetMultipleFloatMethod(targetClass, mPropertyName, numParams);
+ }
+ if (mJniSetter != 0) {
+ if (propertyMap == null) {
+ propertyMap = new HashMap<String, Integer>();
+ sJNISetterPropertyMap.put(targetClass, propertyMap);
+ }
+ propertyMap.put(mPropertyName, mJniSetter);
+ }
+ }
+ } finally {
+ mPropertyMapLock.writeLock().unlock();
+ }
+ }
+ }
+
+ static class MultiIntValuesHolder extends PropertyValuesHolder {
+ private int mJniSetter;
+ private static final HashMap<Class, HashMap<String, Integer>> sJNISetterPropertyMap =
+ new HashMap<Class, HashMap<String, Integer>>();
+
+ public MultiIntValuesHolder(String propertyName, TypeConverter converter,
+ TypeEvaluator evaluator, Object... values) {
+ super(propertyName);
+ setConverter(converter);
+ setObjectValues(values);
+ setEvaluator(evaluator);
+ }
+
+ public MultiIntValuesHolder(String propertyName, TypeConverter converter,
+ TypeEvaluator evaluator, KeyframeSet keyframeSet) {
+ super(propertyName);
+ setConverter(converter);
+ mKeyframeSet = keyframeSet;
+ setEvaluator(evaluator);
+ }
+
+ /**
+ * Internal function to set the value on the target object, using the setter set up
+ * earlier on this PropertyValuesHolder object. This function is called by ObjectAnimator
+ * to handle turning the value calculated by ValueAnimator into a value set on the object
+ * according to the name of the property.
+ *
+ * @param target The target object on which the value is set
+ */
+ @Override
+ void setAnimatedValue(Object target) {
+ int[] values = (int[]) getAnimatedValue();
+ int numParameters = values.length;
+ if (mJniSetter != 0) {
+ switch (numParameters) {
+ case 1:
+ nCallIntMethod(target, mJniSetter, values[0]);
+ break;
+ case 2:
+ nCallTwoIntMethod(target, mJniSetter, values[0], values[1]);
+ break;
+ case 4:
+ nCallFourIntMethod(target, mJniSetter, values[0], values[1],
+ values[2], values[3]);
+ break;
+ default: {
+ nCallMultipleIntMethod(target, mJniSetter, values);
+ break;
+ }
+ }
+ }
+ }
+
+ /**
+ * Internal function (called from ObjectAnimator) to set up the setter and getter
+ * prior to running the animation. No getter can be used for multiple parameters.
+ *
+ * @param target The object on which the setter exists.
+ */
+ @Override
+ void setupSetterAndGetter(Object target) {
+ setupSetter(target.getClass());
+ }
+
+ @Override
+ void setupSetter(Class targetClass) {
+ if (mJniSetter != 0) {
+ return;
+ }
+ try {
+ mPropertyMapLock.writeLock().lock();
+ HashMap<String, Integer> propertyMap = sJNISetterPropertyMap.get(targetClass);
+ if (propertyMap != null) {
+ Integer jniSetterInteger = propertyMap.get(mPropertyName);
+ if (jniSetterInteger != null) {
+ mJniSetter = jniSetterInteger;
+ }
+ }
+ if (mJniSetter == 0) {
+ String methodName = getMethodName("set", mPropertyName);
+ calculateValue(0f);
+ int[] values = (int[]) getAnimatedValue();
+ int numParams = values.length;
+ try {
+ mJniSetter = nGetMultipleIntMethod(targetClass, methodName, numParams);
+ } catch (NoSuchMethodError e) {
+ // try without the 'set' prefix
+ mJniSetter = nGetMultipleIntMethod(targetClass, mPropertyName, numParams);
+ }
+ if (mJniSetter != 0) {
+ if (propertyMap == null) {
+ propertyMap = new HashMap<String, Integer>();
+ sJNISetterPropertyMap.put(targetClass, propertyMap);
+ }
+ propertyMap.put(mPropertyName, mJniSetter);
+ }
+ }
+ } finally {
+ mPropertyMapLock.writeLock().unlock();
+ }
+ }
+ }
+
native static private int nGetIntMethod(Class targetClass, String methodName);
native static private int nGetFloatMethod(Class targetClass, String methodName);
+ native static private int nGetMultipleIntMethod(Class targetClass, String methodName,
+ int numParams);
+ native static private int nGetMultipleFloatMethod(Class targetClass, String methodName,
+ int numParams);
native static private void nCallIntMethod(Object target, int methodID, int arg);
native static private void nCallFloatMethod(Object target, int methodID, float arg);
+ native static private void nCallTwoIntMethod(Object target, int methodID, int arg1, int arg2);
+ native static private void nCallFourIntMethod(Object target, int methodID, int arg1, int arg2,
+ int arg3, int arg4);
+ native static private void nCallMultipleIntMethod(Object target, int methodID, int[] args);
+ native static private void nCallTwoFloatMethod(Object target, int methodID, float arg1,
+ float arg2);
+ native static private void nCallFourFloatMethod(Object target, int methodID, float arg1,
+ float arg2, float arg3, float arg4);
+ native static private void nCallMultipleFloatMethod(Object target, int methodID, float[] args);
}
\ No newline at end of file
diff --git a/core/jni/android_animation_PropertyValuesHolder.cpp b/core/jni/android_animation_PropertyValuesHolder.cpp
index 5991805..73347ea 100644
--- a/core/jni/android_animation_PropertyValuesHolder.cpp
+++ b/core/jni/android_animation_PropertyValuesHolder.cpp
@@ -47,6 +47,32 @@
return mid;
}
+static jmethodID getMultiparameterMethod(JNIEnv* env, jclass targetClass, jstring methodName,
+ jint parameterCount, char parameterType)
+{
+ const char *nativeString = env->GetStringUTFChars(methodName, 0);
+ char *signature = new char[parameterCount + 4];
+ signature[0] = '(';
+ memset(&(signature[1]), parameterType, parameterCount);
+ strcpy(&(signature[parameterCount + 1]), ")V");
+ jmethodID mid = env->GetMethodID(targetClass, nativeString, signature);
+ delete[] signature;
+ env->ReleaseStringUTFChars(methodName, nativeString);
+ return mid;
+}
+
+static jmethodID android_animation_PropertyValuesHolder_getMultipleFloatMethod(
+ JNIEnv* env, jclass pvhClass, jclass targetClass, jstring methodName, jint parameterCount)
+{
+ return getMultiparameterMethod(env, targetClass, methodName, parameterCount, 'F');
+}
+
+static jmethodID android_animation_PropertyValuesHolder_getMultipleIntMethod(
+ JNIEnv* env, jclass pvhClass, jclass targetClass, jstring methodName, jint parameterCount)
+{
+ return getMultiparameterMethod(env, targetClass, methodName, parameterCount, 'I');
+}
+
static void android_animation_PropertyValuesHolder_callIntMethod(
JNIEnv* env, jclass pvhObject, jobject target, jmethodID methodID, int arg)
{
@@ -59,15 +85,85 @@
env->CallVoidMethod(target, methodID, arg);
}
+static void android_animation_PropertyValuesHolder_callTwoFloatMethod(
+ JNIEnv* env, jclass pvhObject, jobject target, jmethodID methodID, float arg1, float arg2)
+{
+ env->CallVoidMethod(target, methodID, arg1, arg2);
+}
+
+static void android_animation_PropertyValuesHolder_callFourFloatMethod(
+ JNIEnv* env, jclass pvhObject, jobject target, jmethodID methodID, float arg1, float arg2,
+ float arg3, float arg4)
+{
+ env->CallVoidMethod(target, methodID, arg1, arg2, arg3, arg4);
+}
+
+static void android_animation_PropertyValuesHolder_callMultipleFloatMethod(
+ JNIEnv* env, jclass pvhObject, jobject target, jmethodID methodID, jfloatArray arg)
+{
+ jsize parameterCount = env->GetArrayLength(arg);
+ jfloat *floatValues = env->GetFloatArrayElements(arg, NULL);
+ jvalue* values = new jvalue[parameterCount];
+ for (int i = 0; i < parameterCount; i++) {
+ values[i].f = floatValues[i];
+ }
+ env->CallVoidMethodA(target, methodID, values);
+ delete[] values;
+ env->ReleaseFloatArrayElements(arg, floatValues, JNI_ABORT);
+}
+
+static void android_animation_PropertyValuesHolder_callTwoIntMethod(
+ JNIEnv* env, jclass pvhObject, jobject target, jmethodID methodID, int arg1, int arg2)
+{
+ env->CallVoidMethod(target, methodID, arg1, arg2);
+}
+
+static void android_animation_PropertyValuesHolder_callFourIntMethod(
+ JNIEnv* env, jclass pvhObject, jobject target, jmethodID methodID, int arg1, int arg2,
+ int arg3, int arg4)
+{
+ env->CallVoidMethod(target, methodID, arg1, arg2, arg3, arg4);
+}
+
+static void android_animation_PropertyValuesHolder_callMultipleIntMethod(
+ JNIEnv* env, jclass pvhObject, jobject target, jmethodID methodID, jintArray arg)
+{
+ jsize parameterCount = env->GetArrayLength(arg);
+ jint *intValues = env->GetIntArrayElements(arg, NULL);
+ jvalue* values = new jvalue[parameterCount];
+ for (int i = 0; i < parameterCount; i++) {
+ values[i].i = intValues[i];
+ }
+ env->CallVoidMethodA(target, methodID, values);
+ delete[] values;
+ env->ReleaseIntArrayElements(arg, intValues, JNI_ABORT);
+}
+
static JNINativeMethod gMethods[] = {
{ "nGetIntMethod", "(Ljava/lang/Class;Ljava/lang/String;)I",
(void*)android_animation_PropertyValuesHolder_getIntMethod },
{ "nGetFloatMethod", "(Ljava/lang/Class;Ljava/lang/String;)I",
(void*)android_animation_PropertyValuesHolder_getFloatMethod },
+ { "nGetMultipleFloatMethod", "(Ljava/lang/Class;Ljava/lang/String;I)I",
+ (void*)android_animation_PropertyValuesHolder_getMultipleFloatMethod },
+ { "nGetMultipleIntMethod", "(Ljava/lang/Class;Ljava/lang/String;I)I",
+ (void*)android_animation_PropertyValuesHolder_getMultipleIntMethod },
{ "nCallIntMethod", "(Ljava/lang/Object;II)V",
(void*)android_animation_PropertyValuesHolder_callIntMethod },
{ "nCallFloatMethod", "(Ljava/lang/Object;IF)V",
- (void*)android_animation_PropertyValuesHolder_callFloatMethod }
+ (void*)android_animation_PropertyValuesHolder_callFloatMethod },
+ { "nCallTwoFloatMethod", "(Ljava/lang/Object;IFF)V",
+ (void*)android_animation_PropertyValuesHolder_callTwoFloatMethod },
+ { "nCallFourFloatMethod", "(Ljava/lang/Object;IFFFF)V",
+ (void*)android_animation_PropertyValuesHolder_callFourFloatMethod },
+ { "nCallMultipleFloatMethod", "(Ljava/lang/Object;I[F)V",
+ (void*)android_animation_PropertyValuesHolder_callMultipleFloatMethod },
+ { "nCallTwoIntMethod", "(Ljava/lang/Object;III)V",
+ (void*)android_animation_PropertyValuesHolder_callTwoIntMethod },
+ { "nCallFourIntMethod", "(Ljava/lang/Object;IIIII)V",
+ (void*)android_animation_PropertyValuesHolder_callFourIntMethod },
+ { "nCallMultipleIntMethod", "(Ljava/lang/Object;I[I)V",
+ (void*)android_animation_PropertyValuesHolder_callMultipleIntMethod },
};
int register_android_animation_PropertyValuesHolder(JNIEnv* env)