Support for multiple value animations.
Bug 2805977 Support for multi-value setters in ObjectAnimator. Change-Id: I7854dfcb82372afc6d9afb4c50a289ff9d41574e
This commit is contained in:
@@ -2433,11 +2433,23 @@ package android.animation {
|
||||
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);
|
||||
@@ -2510,6 +2522,10 @@ package android.animation {
|
||||
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...);
|
||||
@@ -2528,6 +2544,12 @@ package android.animation {
|
||||
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...);
|
||||
|
||||
77
core/java/android/animation/FloatArrayEvaluator.java
Normal file
77
core/java/android/animation/FloatArrayEvaluator.java
Normal file
@@ -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;
|
||||
}
|
||||
}
|
||||
75
core/java/android/animation/IntArrayEvaluator.java
Normal file
75
core/java/android/animation/IntArrayEvaluator.java
Normal file
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -227,6 +227,53 @@ public final class ObjectAnimator extends ValueAnimator {
|
||||
return anim;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
@@ -266,6 +313,54 @@ public final class ObjectAnimator extends ValueAnimator {
|
||||
return anim;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
|
||||
@@ -169,6 +169,84 @@ public class PropertyValuesHolder implements Cloneable {
|
||||
return new IntPropertyValuesHolder(property, values);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
@@ -191,6 +269,83 @@ public class PropertyValuesHolder implements Cloneable {
|
||||
return new FloatPropertyValuesHolder(property, values);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
@@ -1078,8 +1233,227 @@ public class PropertyValuesHolder implements Cloneable {
|
||||
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
@@ -47,6 +47,32 @@ static jmethodID android_animation_PropertyValuesHolder_getFloatMethod(
|
||||
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 @@ static void android_animation_PropertyValuesHolder_callFloatMethod(
|
||||
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)
|
||||
|
||||
Reference in New Issue
Block a user