Merge "Setter values can now have different type than animated values."
This commit is contained in:
@@ -2521,6 +2521,7 @@ package android.animation {
|
||||
method public static android.animation.ObjectAnimator ofInt(T, android.util.Property<T, java.lang.Integer>, int...);
|
||||
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...);
|
||||
method public static android.animation.ObjectAnimator ofPropertyValuesHolder(java.lang.Object, android.animation.PropertyValuesHolder...);
|
||||
method public void setAutoCancel(boolean);
|
||||
method public void setProperty(android.util.Property);
|
||||
@@ -2538,6 +2539,8 @@ package android.animation {
|
||||
method public static android.animation.PropertyValuesHolder ofKeyframe(android.util.Property, 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...);
|
||||
method public void setConverter(android.animation.TypeConverter);
|
||||
method public void setEvaluator(android.animation.TypeEvaluator);
|
||||
method public void setFloatValues(float...);
|
||||
method public void setIntValues(int...);
|
||||
@@ -2566,6 +2569,12 @@ package android.animation {
|
||||
method public abstract float getInterpolation(float);
|
||||
}
|
||||
|
||||
public abstract class TypeConverter {
|
||||
ctor public TypeConverter(java.lang.Class<T>, java.lang.Class<V>);
|
||||
method public abstract V convert(T);
|
||||
method public T convertBack(V);
|
||||
}
|
||||
|
||||
public abstract interface TypeEvaluator {
|
||||
method public abstract T evaluate(float, T, T);
|
||||
}
|
||||
|
||||
@@ -191,7 +191,7 @@ public final class ObjectAnimator extends ValueAnimator {
|
||||
|
||||
/**
|
||||
* Constructs and returns an ObjectAnimator that animates between int values. A single
|
||||
* value implies that that value is the one being animated to. Two values imply a starting
|
||||
* 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
|
||||
* along the way, and an ending value (these values will be distributed evenly across
|
||||
* the duration of the animation).
|
||||
@@ -211,7 +211,7 @@ public final class ObjectAnimator extends ValueAnimator {
|
||||
|
||||
/**
|
||||
* Constructs and returns an ObjectAnimator that animates between int values. A single
|
||||
* value implies that that value is the one being animated to. Two values imply a starting
|
||||
* 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
|
||||
* along the way, and an ending value (these values will be distributed evenly across
|
||||
* the duration of the animation).
|
||||
@@ -229,7 +229,7 @@ public final class ObjectAnimator extends ValueAnimator {
|
||||
|
||||
/**
|
||||
* 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 a starting
|
||||
* 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
|
||||
* along the way, and an ending value (these values will be distributed evenly across
|
||||
* the duration of the animation).
|
||||
@@ -249,7 +249,7 @@ public final class ObjectAnimator extends ValueAnimator {
|
||||
|
||||
/**
|
||||
* 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 a starting
|
||||
* 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
|
||||
* along the way, and an ending value (these values will be distributed evenly across
|
||||
* the duration of the animation).
|
||||
@@ -268,7 +268,7 @@ public final class ObjectAnimator extends ValueAnimator {
|
||||
|
||||
/**
|
||||
* 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 a starting
|
||||
* 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
|
||||
* along the way, and an ending value (these values will be distributed evenly across
|
||||
* the duration of the animation).
|
||||
@@ -293,7 +293,7 @@ public final class ObjectAnimator extends ValueAnimator {
|
||||
|
||||
/**
|
||||
* 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 a starting
|
||||
* 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
|
||||
* along the way, and an ending value (these values will be distributed evenly across
|
||||
* the duration of the animation).
|
||||
@@ -314,6 +314,32 @@ public final class ObjectAnimator extends ValueAnimator {
|
||||
return anim;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
* along the way, and an ending value (these values will be distributed evenly across
|
||||
* the duration of the animation). This variant supplies a <code>TypeConverter</code> to
|
||||
* convert from the animated values to the type of the property. If only one value is
|
||||
* supplied, the <code>TypeConverter</code> must implement
|
||||
* {@link TypeConverter#convertBack(Object)} to retrieve the current value.
|
||||
*
|
||||
* @param target The object whose property is to be animated.
|
||||
* @param property The property being animated.
|
||||
* @param converter Converts the animated object to the Property type.
|
||||
* @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, V, P> ObjectAnimator ofObject(T target, Property<T, P> property,
|
||||
TypeConverter<V, P> converter, TypeEvaluator<V> evaluator, V... values) {
|
||||
PropertyValuesHolder pvh = PropertyValuesHolder.ofObject(property, converter, evaluator,
|
||||
values);
|
||||
return ofPropertyValuesHolder(target, pvh);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs and returns an ObjectAnimator that animates between the sets of values specified
|
||||
* in <code>PropertyValueHolder</code> objects. This variant should be used when animating
|
||||
|
||||
@@ -123,6 +123,11 @@ public class PropertyValuesHolder implements Cloneable {
|
||||
*/
|
||||
private Object mAnimatedValue;
|
||||
|
||||
/**
|
||||
* Converts from the source Object type to the setter Object type.
|
||||
*/
|
||||
private TypeConverter mConverter;
|
||||
|
||||
/**
|
||||
* Internal utility constructor, used by the factory methods to set the property name.
|
||||
* @param propertyName The name of the property for this holder.
|
||||
@@ -226,6 +231,34 @@ public class PropertyValuesHolder implements Cloneable {
|
||||
return pvh;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs and returns a PropertyValuesHolder with a given property and
|
||||
* set of Object values. This variant also takes a TypeEvaluator because the system
|
||||
* cannot automatically interpolate between objects of unknown type. This variant also
|
||||
* takes a <code>TypeConverter</code> to convert from animated values to the type
|
||||
* of the property. If only one value is supplied, the <code>TypeConverter</code>
|
||||
* must implement {@link TypeConverter#convertBack(Object)} to retrieve the current
|
||||
* value.
|
||||
*
|
||||
* @param property The property being animated. Should not be null.
|
||||
* @param converter Converts the animated object to the Property type.
|
||||
* @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 #setConverter(TypeConverter)
|
||||
* @see TypeConverter
|
||||
*/
|
||||
public static <T, V> PropertyValuesHolder ofObject(Property<?, V> property,
|
||||
TypeConverter<T, V> converter, TypeEvaluator<T> evaluator, T... values) {
|
||||
PropertyValuesHolder pvh = new PropertyValuesHolder(property);
|
||||
pvh.setConverter(converter);
|
||||
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
|
||||
@@ -360,6 +393,14 @@ public class PropertyValuesHolder implements Cloneable {
|
||||
mKeyframeSet = KeyframeSet.ofObject(values);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the converter to convert from the values type to the setter's parameter type.
|
||||
* @param converter The converter to use to convert values.
|
||||
*/
|
||||
public void setConverter(TypeConverter converter) {
|
||||
mConverter = converter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine the setter or getter function using the JavaBeans convention of setFoo or
|
||||
* getFoo for a property named 'foo'. This function figures out what the name of the
|
||||
@@ -389,22 +430,24 @@ public class PropertyValuesHolder implements Cloneable {
|
||||
} else {
|
||||
args = new Class[1];
|
||||
Class typeVariants[];
|
||||
if (mValueType.equals(Float.class)) {
|
||||
if (valueType.equals(Float.class)) {
|
||||
typeVariants = FLOAT_VARIANTS;
|
||||
} else if (mValueType.equals(Integer.class)) {
|
||||
} else if (valueType.equals(Integer.class)) {
|
||||
typeVariants = INTEGER_VARIANTS;
|
||||
} else if (mValueType.equals(Double.class)) {
|
||||
} else if (valueType.equals(Double.class)) {
|
||||
typeVariants = DOUBLE_VARIANTS;
|
||||
} else {
|
||||
typeVariants = new Class[1];
|
||||
typeVariants[0] = mValueType;
|
||||
typeVariants[0] = valueType;
|
||||
}
|
||||
for (Class typeVariant : typeVariants) {
|
||||
args[0] = typeVariant;
|
||||
try {
|
||||
returnVal = targetClass.getMethod(methodName, args);
|
||||
// change the value type to suit
|
||||
mValueType = typeVariant;
|
||||
if (mConverter == null) {
|
||||
// change the value type to suit
|
||||
mValueType = typeVariant;
|
||||
}
|
||||
return returnVal;
|
||||
} catch (NoSuchMethodException e) {
|
||||
// Swallow the error and keep trying other variants
|
||||
@@ -415,7 +458,7 @@ public class PropertyValuesHolder implements Cloneable {
|
||||
|
||||
if (returnVal == null) {
|
||||
Log.w("PropertyValuesHolder", "Method " +
|
||||
getMethodName(prefix, mPropertyName) + "() with type " + mValueType +
|
||||
getMethodName(prefix, mPropertyName) + "() with type " + valueType +
|
||||
" not found on target class " + targetClass);
|
||||
}
|
||||
|
||||
@@ -465,7 +508,8 @@ public class PropertyValuesHolder implements Cloneable {
|
||||
* @param targetClass The Class on which the requested method should exist.
|
||||
*/
|
||||
void setupSetter(Class targetClass) {
|
||||
mSetter = setupSetterOrGetter(targetClass, sSetterPropertyMap, "set", mValueType);
|
||||
Class<?> propertyType = mConverter == null ? mValueType : mConverter.getTargetType();
|
||||
mSetter = setupSetterOrGetter(targetClass, sSetterPropertyMap, "set", propertyType);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -489,10 +533,13 @@ public class PropertyValuesHolder implements Cloneable {
|
||||
if (mProperty != null) {
|
||||
// check to make sure that mProperty is on the class of target
|
||||
try {
|
||||
Object testValue = mProperty.get(target);
|
||||
Object testValue = null;
|
||||
for (Keyframe kf : mKeyframeSet.mKeyframes) {
|
||||
if (!kf.hasValue()) {
|
||||
kf.setValue(mProperty.get(target));
|
||||
if (testValue == null) {
|
||||
testValue = convertBack(mProperty.get(target));
|
||||
}
|
||||
kf.setValue(testValue);
|
||||
}
|
||||
}
|
||||
return;
|
||||
@@ -516,7 +563,8 @@ public class PropertyValuesHolder implements Cloneable {
|
||||
}
|
||||
}
|
||||
try {
|
||||
kf.setValue(mGetter.invoke(target));
|
||||
Object value = convertBack(mGetter.invoke(target));
|
||||
kf.setValue(value);
|
||||
} catch (InvocationTargetException e) {
|
||||
Log.e("PropertyValuesHolder", e.toString());
|
||||
} catch (IllegalAccessException e) {
|
||||
@@ -526,6 +574,18 @@ public class PropertyValuesHolder implements Cloneable {
|
||||
}
|
||||
}
|
||||
|
||||
private Object convertBack(Object value) {
|
||||
if (mConverter != null) {
|
||||
value = mConverter.convertBack(value);
|
||||
if (value == null) {
|
||||
throw new IllegalArgumentException("Converter "
|
||||
+ mConverter.getClass().getName()
|
||||
+ " must implement convertBack and not return null.");
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility function to set the value stored in a particular Keyframe. The value used is
|
||||
* whatever the value is for the property name specified in the keyframe on the target object.
|
||||
@@ -535,7 +595,8 @@ public class PropertyValuesHolder implements Cloneable {
|
||||
*/
|
||||
private void setupValue(Object target, Keyframe kf) {
|
||||
if (mProperty != null) {
|
||||
kf.setValue(mProperty.get(target));
|
||||
Object value = convertBack(mProperty.get(target));
|
||||
kf.setValue(value);
|
||||
}
|
||||
try {
|
||||
if (mGetter == null) {
|
||||
@@ -546,7 +607,8 @@ public class PropertyValuesHolder implements Cloneable {
|
||||
return;
|
||||
}
|
||||
}
|
||||
kf.setValue(mGetter.invoke(target));
|
||||
Object value = convertBack(mGetter.invoke(target));
|
||||
kf.setValue(value);
|
||||
} catch (InvocationTargetException e) {
|
||||
Log.e("PropertyValuesHolder", e.toString());
|
||||
} catch (IllegalAccessException e) {
|
||||
@@ -657,7 +719,8 @@ public class PropertyValuesHolder implements Cloneable {
|
||||
* @param fraction The elapsed, interpolated fraction of the animation.
|
||||
*/
|
||||
void calculateValue(float fraction) {
|
||||
mAnimatedValue = mKeyframeSet.getValue(fraction);
|
||||
Object value = mKeyframeSet.getValue(fraction);
|
||||
mAnimatedValue = mConverter == null ? value : mConverter.convert(value);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
68
core/java/android/animation/TypeConverter.java
Normal file
68
core/java/android/animation/TypeConverter.java
Normal file
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* Abstract base class used convert type T to another type V. This
|
||||
* is necessary when the value types of in animation are different
|
||||
* from the property type.
|
||||
* @see PropertyValuesHolder#setConverter(TypeConverter)
|
||||
*/
|
||||
public abstract class TypeConverter<T, V> {
|
||||
private Class<T> mFromClass;
|
||||
private Class<V> mToClass;
|
||||
|
||||
public TypeConverter(Class<T> fromClass, Class<V> toClass) {
|
||||
mFromClass = fromClass;
|
||||
mToClass = toClass;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the target converted type. Used by the animation system to determine
|
||||
* the proper setter function to call.
|
||||
* @return The Class to convert the input to.
|
||||
*/
|
||||
Class<V> getTargetType() {
|
||||
return mToClass;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the source conversion type.
|
||||
*/
|
||||
Class<T> getSourceType() {
|
||||
return mFromClass;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a value from one type to another.
|
||||
* @param value The Object to convert.
|
||||
* @return A value of type V, converted from <code>value</code>.
|
||||
*/
|
||||
public abstract V convert(T value);
|
||||
|
||||
/**
|
||||
* Does a conversion from the target type back to the source type. The subclass
|
||||
* must implement this when a TypeConverter is used in animations and current
|
||||
* values will need to be read for an animation. By default, this will return null,
|
||||
* indicating that back-conversion is not supported.
|
||||
* @param value The Object to convert.
|
||||
* @return A value of type T, converted from <code>value</code>.
|
||||
*/
|
||||
public T convertBack(V value) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user