diff options
Diffstat (limited to 'actionbarsherlock/src/com/actionbarsherlock/internal/nineoldandroids/animation/PropertyValuesHolder.java')
-rw-r--r-- | actionbarsherlock/src/com/actionbarsherlock/internal/nineoldandroids/animation/PropertyValuesHolder.java | 1012 |
1 files changed, 0 insertions, 1012 deletions
diff --git a/actionbarsherlock/src/com/actionbarsherlock/internal/nineoldandroids/animation/PropertyValuesHolder.java b/actionbarsherlock/src/com/actionbarsherlock/internal/nineoldandroids/animation/PropertyValuesHolder.java deleted file mode 100644 index 84f7504ab..000000000 --- a/actionbarsherlock/src/com/actionbarsherlock/internal/nineoldandroids/animation/PropertyValuesHolder.java +++ /dev/null @@ -1,1012 +0,0 @@ -/* - * Copyright (C) 2010 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 com.actionbarsherlock.internal.nineoldandroids.animation; - -//import android.util.FloatProperty; -//import android.util.IntProperty; -import android.util.Log; -//import android.util.Property; - -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.HashMap; -import java.util.concurrent.locks.ReentrantReadWriteLock; - -/** - * This class holds information about a property and the values that that property - * should take on during an animation. PropertyValuesHolder objects can be used to create - * animations with ValueAnimator or ObjectAnimator that operate on several different properties - * in parallel. - */ -@SuppressWarnings({"rawtypes", "unchecked"}) -public class PropertyValuesHolder implements Cloneable { - - /** - * The name of the property associated with the values. This need not be a real property, - * unless this object is being used with ObjectAnimator. But this is the name by which - * aniamted values are looked up with getAnimatedValue(String) in ValueAnimator. - */ - String mPropertyName; - - /** - * @hide - */ - //protected Property mProperty; - - /** - * The setter function, if needed. ObjectAnimator hands off this functionality to - * PropertyValuesHolder, since it holds all of the per-property information. This - * property is automatically - * derived when the animation starts in setupSetterAndGetter() if using ObjectAnimator. - */ - Method mSetter = null; - - /** - * The getter function, if needed. ObjectAnimator hands off this functionality to - * PropertyValuesHolder, since it holds all of the per-property information. This - * property is automatically - * derived when the animation starts in setupSetterAndGetter() if using ObjectAnimator. - * The getter is only derived and used if one of the values is null. - */ - private Method mGetter = null; - - /** - * The type of values supplied. This information is used both in deriving the setter/getter - * functions and in deriving the type of TypeEvaluator. - */ - Class mValueType; - - /** - * The set of keyframes (time/value pairs) that define this animation. - */ - KeyframeSet mKeyframeSet = null; - - - // type evaluators for the primitive types handled by this implementation - private static final TypeEvaluator sIntEvaluator = new IntEvaluator(); - private static final TypeEvaluator sFloatEvaluator = new FloatEvaluator(); - - // We try several different types when searching for appropriate setter/getter functions. - // The caller may have supplied values in a type that does not match the setter/getter - // functions (such as the integers 0 and 1 to represent floating point values for alpha). - // Also, the use of generics in constructors means that we end up with the Object versions - // of primitive types (Float vs. float). But most likely, the setter/getter functions - // will take primitive types instead. - // So we supply an ordered array of other types to try before giving up. - private static Class[] FLOAT_VARIANTS = {float.class, Float.class, double.class, int.class, - Double.class, Integer.class}; - private static Class[] INTEGER_VARIANTS = {int.class, Integer.class, float.class, double.class, - Float.class, Double.class}; - private static Class[] DOUBLE_VARIANTS = {double.class, Double.class, float.class, int.class, - Float.class, Integer.class}; - - // These maps hold all property entries for a particular class. This map - // is used to speed up property/setter/getter lookups for a given class/property - // combination. No need to use reflection on the combination more than once. - private static final HashMap<Class, HashMap<String, Method>> sSetterPropertyMap = - new HashMap<Class, HashMap<String, Method>>(); - private static final HashMap<Class, HashMap<String, Method>> sGetterPropertyMap = - new HashMap<Class, HashMap<String, Method>>(); - - // This lock is used to ensure that only one thread is accessing the property maps - // at a time. - final ReentrantReadWriteLock mPropertyMapLock = new ReentrantReadWriteLock(); - - // Used to pass single value to varargs parameter in setter invocation - final Object[] mTmpValueArray = new Object[1]; - - /** - * The type evaluator used to calculate the animated values. This evaluator is determined - * automatically based on the type of the start/end objects passed into the constructor, - * but the system only knows about the primitive types int and float. Any other - * type will need to set the evaluator to a custom evaluator for that type. - */ - private TypeEvaluator mEvaluator; - - /** - * The value most recently calculated by calculateValue(). This is set during - * that function and might be retrieved later either by ValueAnimator.animatedValue() or - * by the property-setting logic in ObjectAnimator.animatedValue(). - */ - private Object mAnimatedValue; - - /** - * Internal utility constructor, used by the factory methods to set the property name. - * @param propertyName The name of the property for this holder. - */ - private PropertyValuesHolder(String propertyName) { - mPropertyName = propertyName; - } - - /** - * Internal utility constructor, used by the factory methods to set the property. - * @param property The property for this holder. - */ - //private PropertyValuesHolder(Property property) { - // mProperty = property; - // if (property != null) { - // mPropertyName = property.getName(); - // } - //} - - /** - * Constructs and returns a PropertyValuesHolder with a given property name and - * set of int values. - * @param propertyName The name of the property being animated. - * @param values The values that the named property will animate between. - * @return PropertyValuesHolder The constructed PropertyValuesHolder object. - */ - public static PropertyValuesHolder ofInt(String propertyName, int... values) { - return new IntPropertyValuesHolder(propertyName, values); - } - - /** - * Constructs and returns a PropertyValuesHolder with a given property and - * set of int values. - * @param property The property being animated. Should not be null. - * @param values The values that the property will animate between. - * @return PropertyValuesHolder The constructed PropertyValuesHolder object. - */ - //public static PropertyValuesHolder ofInt(Property<?, Integer> property, int... values) { - // return new IntPropertyValuesHolder(property, values); - //} - - /** - * Constructs and returns a PropertyValuesHolder with a given property name and - * set of float values. - * @param propertyName The name of the property being animated. - * @param values The values that the named property will animate between. - * @return PropertyValuesHolder The constructed PropertyValuesHolder object. - */ - public static PropertyValuesHolder ofFloat(String propertyName, float... values) { - return new FloatPropertyValuesHolder(propertyName, values); - } - - /** - * Constructs and returns a PropertyValuesHolder with a given property and - * set of float values. - * @param property The property being animated. Should not be null. - * @param values The values that the property will animate between. - * @return PropertyValuesHolder The constructed PropertyValuesHolder object. - */ - //public static PropertyValuesHolder ofFloat(Property<?, Float> property, float... values) { - // return new FloatPropertyValuesHolder(property, values); - //} - - /** - * 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. - * - * @param propertyName The name of the property being animated. - * @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 named property will animate between. - * @return PropertyValuesHolder The constructed PropertyValuesHolder object. - */ - public static PropertyValuesHolder ofObject(String propertyName, TypeEvaluator evaluator, - Object... values) { - PropertyValuesHolder pvh = new PropertyValuesHolder(propertyName); - pvh.setObjectValues(values); - pvh.setEvaluator(evaluator); - return pvh; - } - - /** - * Constructs and returns a PropertyValuesHolder 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. - * - * @param property The property being animated. Should not be null. - * @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. - */ - //public static <V> PropertyValuesHolder ofObject(Property property, - // TypeEvaluator<V> evaluator, V... values) { - // PropertyValuesHolder pvh = new PropertyValuesHolder(property); - // pvh.setObjectValues(values); - // pvh.setEvaluator(evaluator); - // return pvh; - //} - - /** - * Constructs and returns a PropertyValuesHolder object with the specified property name and set - * of values. These values can be of any type, but the type should be consistent so that - * an appropriate {@link android.animation.TypeEvaluator} can be found that matches - * the common type. - * <p>If there is only one value, it is assumed to be the end value of an animation, - * and an initial value will be derived, if possible, by calling a getter function - * on the object. Also, if any value is null, the value will be filled in when the animation - * starts in the same way. This mechanism of automatically getting null values only works - * if the PropertyValuesHolder object is used in conjunction - * {@link ObjectAnimator}, and with a getter function - * derived automatically from <code>propertyName</code>, since otherwise PropertyValuesHolder has - * no way of determining what the value should be. - * @param propertyName The name of the property associated with this set of values. This - * can be the actual property name to be used when using a ObjectAnimator object, or - * just a name used to get animated values, such as if this object is used with an - * ValueAnimator object. - * @param values The set of values to animate between. - */ - public static PropertyValuesHolder ofKeyframe(String propertyName, Keyframe... values) { - KeyframeSet keyframeSet = KeyframeSet.ofKeyframe(values); - if (keyframeSet instanceof IntKeyframeSet) { - return new IntPropertyValuesHolder(propertyName, (IntKeyframeSet) keyframeSet); - } else if (keyframeSet instanceof FloatKeyframeSet) { - return new FloatPropertyValuesHolder(propertyName, (FloatKeyframeSet) keyframeSet); - } - else { - PropertyValuesHolder pvh = new PropertyValuesHolder(propertyName); - pvh.mKeyframeSet = keyframeSet; - pvh.mValueType = values[0].getType(); - return pvh; - } - } - - /** - * Constructs and returns a PropertyValuesHolder object with the specified property and set - * of values. These values can be of any type, but the type should be consistent so that - * an appropriate {@link android.animation.TypeEvaluator} can be found that matches - * the common type. - * <p>If there is only one value, it is assumed to be the end value of an animation, - * and an initial value will be derived, if possible, by calling the property's - * {@link android.util.Property#get(Object)} function. - * Also, if any value is null, the value will be filled in when the animation - * starts in the same way. This mechanism of automatically getting null values only works - * if the PropertyValuesHolder object is used in conjunction with - * {@link ObjectAnimator}, since otherwise PropertyValuesHolder has - * no way of determining what the value should be. - * @param property The property associated with this set of values. Should not be null. - * @param values The set of values to animate between. - */ - //public static PropertyValuesHolder ofKeyframe(Property property, Keyframe... values) { - // KeyframeSet keyframeSet = KeyframeSet.ofKeyframe(values); - // if (keyframeSet instanceof IntKeyframeSet) { - // return new IntPropertyValuesHolder(property, (IntKeyframeSet) keyframeSet); - // } else if (keyframeSet instanceof FloatKeyframeSet) { - // return new FloatPropertyValuesHolder(property, (FloatKeyframeSet) keyframeSet); - // } - // else { - // PropertyValuesHolder pvh = new PropertyValuesHolder(property); - // pvh.mKeyframeSet = keyframeSet; - // pvh.mValueType = ((Keyframe)values[0]).getType(); - // return pvh; - // } - //} - - /** - * Set the animated values for this object to this set of ints. - * If there is only one value, it is assumed to be the end value of an animation, - * and an initial value will be derived, if possible, by calling a getter function - * on the object. Also, if any value is null, the value will be filled in when the animation - * starts in the same way. This mechanism of automatically getting null values only works - * if the PropertyValuesHolder object is used in conjunction - * {@link ObjectAnimator}, and with a getter function - * derived automatically from <code>propertyName</code>, since otherwise PropertyValuesHolder has - * no way of determining what the value should be. - * - * @param values One or more values that the animation will animate between. - */ - public void setIntValues(int... values) { - mValueType = int.class; - mKeyframeSet = KeyframeSet.ofInt(values); - } - - /** - * Set the animated values for this object to this set of floats. - * If there is only one value, it is assumed to be the end value of an animation, - * and an initial value will be derived, if possible, by calling a getter function - * on the object. Also, if any value is null, the value will be filled in when the animation - * starts in the same way. This mechanism of automatically getting null values only works - * if the PropertyValuesHolder object is used in conjunction - * {@link ObjectAnimator}, and with a getter function - * derived automatically from <code>propertyName</code>, since otherwise PropertyValuesHolder has - * no way of determining what the value should be. - * - * @param values One or more values that the animation will animate between. - */ - public void setFloatValues(float... values) { - mValueType = float.class; - mKeyframeSet = KeyframeSet.ofFloat(values); - } - - /** - * Set the animated values for this object to this set of Keyframes. - * - * @param values One or more values that the animation will animate between. - */ - public void setKeyframes(Keyframe... values) { - int numKeyframes = values.length; - Keyframe keyframes[] = new Keyframe[Math.max(numKeyframes,2)]; - mValueType = values[0].getType(); - for (int i = 0; i < numKeyframes; ++i) { - keyframes[i] = values[i]; - } - mKeyframeSet = new KeyframeSet(keyframes); - } - - /** - * Set the animated values for this object to this set of Objects. - * If there is only one value, it is assumed to be the end value of an animation, - * and an initial value will be derived, if possible, by calling a getter function - * on the object. Also, if any value is null, the value will be filled in when the animation - * starts in the same way. This mechanism of automatically getting null values only works - * if the PropertyValuesHolder object is used in conjunction - * {@link ObjectAnimator}, and with a getter function - * derived automatically from <code>propertyName</code>, since otherwise PropertyValuesHolder has - * no way of determining what the value should be. - * - * @param values One or more values that the animation will animate between. - */ - public void setObjectValues(Object... values) { - mValueType = values[0].getClass(); - mKeyframeSet = KeyframeSet.ofObject(values); - } - - /** - * Determine the setter or getter function using the JavaBeans convention of setFoo or - * getFoo for a property named 'foo'. This function figures out what the name of the - * function should be and uses reflection to find the Method with that name on the - * target object. - * - * @param targetClass The class to search for the method - * @param prefix "set" or "get", depending on whether we need a setter or getter. - * @param valueType The type of the parameter (in the case of a setter). This type - * is derived from the values set on this PropertyValuesHolder. This type is used as - * a first guess at the parameter type, but we check for methods with several different - * types to avoid problems with slight mis-matches between supplied values and actual - * value types used on the setter. - * @return Method the method associated with mPropertyName. - */ - private Method getPropertyFunction(Class targetClass, String prefix, Class valueType) { - // TODO: faster implementation... - Method returnVal = null; - String methodName = getMethodName(prefix, mPropertyName); - Class args[] = null; - if (valueType == null) { - try { - returnVal = targetClass.getMethod(methodName, args); - } catch (NoSuchMethodException e) { - Log.e("PropertyValuesHolder", targetClass.getSimpleName() + " - " + - "Couldn't find no-arg method for property " + mPropertyName + ": " + e); - } - } else { - args = new Class[1]; - Class typeVariants[]; - if (mValueType.equals(Float.class)) { - typeVariants = FLOAT_VARIANTS; - } else if (mValueType.equals(Integer.class)) { - typeVariants = INTEGER_VARIANTS; - } else if (mValueType.equals(Double.class)) { - typeVariants = DOUBLE_VARIANTS; - } else { - typeVariants = new Class[1]; - typeVariants[0] = mValueType; - } - for (Class typeVariant : typeVariants) { - args[0] = typeVariant; - try { - returnVal = targetClass.getMethod(methodName, args); - // change the value type to suit - mValueType = typeVariant; - return returnVal; - } catch (NoSuchMethodException e) { - // Swallow the error and keep trying other variants - } - } - // If we got here, then no appropriate function was found - Log.e("PropertyValuesHolder", - "Couldn't find " + prefix + "ter property " + mPropertyName + - " for " + targetClass.getSimpleName() + - " with value type "+ mValueType); - } - - return returnVal; - } - - - /** - * Returns the setter or getter requested. This utility function checks whether the - * requested method exists in the propertyMapMap cache. If not, it calls another - * utility function to request the Method from the targetClass directly. - * @param targetClass The Class on which the requested method should exist. - * @param propertyMapMap The cache of setters/getters derived so far. - * @param prefix "set" or "get", for the setter or getter. - * @param valueType The type of parameter passed into the method (null for getter). - * @return Method the method associated with mPropertyName. - */ - private Method setupSetterOrGetter(Class targetClass, - HashMap<Class, HashMap<String, Method>> propertyMapMap, - String prefix, Class valueType) { - Method setterOrGetter = null; - try { - // Have to lock property map prior to reading it, to guard against - // another thread putting something in there after we've checked it - // but before we've added an entry to it - mPropertyMapLock.writeLock().lock(); - HashMap<String, Method> propertyMap = propertyMapMap.get(targetClass); - if (propertyMap != null) { - setterOrGetter = propertyMap.get(mPropertyName); - } - if (setterOrGetter == null) { - setterOrGetter = getPropertyFunction(targetClass, prefix, valueType); - if (propertyMap == null) { - propertyMap = new HashMap<String, Method>(); - propertyMapMap.put(targetClass, propertyMap); - } - propertyMap.put(mPropertyName, setterOrGetter); - } - } finally { - mPropertyMapLock.writeLock().unlock(); - } - return setterOrGetter; - } - - /** - * Utility function to get the setter from targetClass - * @param targetClass The Class on which the requested method should exist. - */ - void setupSetter(Class targetClass) { - mSetter = setupSetterOrGetter(targetClass, sSetterPropertyMap, "set", mValueType); - } - - /** - * Utility function to get the getter from targetClass - */ - private void setupGetter(Class targetClass) { - mGetter = setupSetterOrGetter(targetClass, sGetterPropertyMap, "get", null); - } - - /** - * Internal function (called from ObjectAnimator) to set up the setter and getter - * prior to running the animation. If the setter has not been manually set for this - * object, it will be derived automatically given the property name, target object, and - * types of values supplied. If no getter has been set, it will be supplied iff any of the - * supplied values was null. If there is a null value, then the getter (supplied or derived) - * will be called to set those null values to the current value of the property - * on the target object. - * @param target The object on which the setter (and possibly getter) exist. - */ - void setupSetterAndGetter(Object target) { - //if (mProperty != null) { - // // check to make sure that mProperty is on the class of target - // try { - // Object testValue = mProperty.get(target); - // for (Keyframe kf : mKeyframeSet.mKeyframes) { - // if (!kf.hasValue()) { - // kf.setValue(mProperty.get(target)); - // } - // } - // return; - // } catch (ClassCastException e) { - // Log.e("PropertyValuesHolder","No such property (" + mProperty.getName() + - // ") on target object " + target + ". Trying reflection instead"); - // mProperty = null; - // } - //} - Class targetClass = target.getClass(); - if (mSetter == null) { - setupSetter(targetClass); - } - for (Keyframe kf : mKeyframeSet.mKeyframes) { - if (!kf.hasValue()) { - if (mGetter == null) { - setupGetter(targetClass); - } - try { - kf.setValue(mGetter.invoke(target)); - } catch (InvocationTargetException e) { - Log.e("PropertyValuesHolder", e.toString()); - } catch (IllegalAccessException e) { - Log.e("PropertyValuesHolder", e.toString()); - } - } - } - } - - /** - * 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. - * - * @param target The target object from which the current value should be extracted. - * @param kf The keyframe which holds the property name and value. - */ - private void setupValue(Object target, Keyframe kf) { - //if (mProperty != null) { - // kf.setValue(mProperty.get(target)); - //} - try { - if (mGetter == null) { - Class targetClass = target.getClass(); - setupGetter(targetClass); - } - kf.setValue(mGetter.invoke(target)); - } catch (InvocationTargetException e) { - Log.e("PropertyValuesHolder", e.toString()); - } catch (IllegalAccessException e) { - Log.e("PropertyValuesHolder", e.toString()); - } - } - - /** - * This function is called by ObjectAnimator when setting the start values for an animation. - * The start values are set according to the current values in the target object. The - * property whose value is extracted is whatever is specified by the propertyName of this - * PropertyValuesHolder object. - * - * @param target The object which holds the start values that should be set. - */ - void setupStartValue(Object target) { - setupValue(target, mKeyframeSet.mKeyframes.get(0)); - } - - /** - * This function is called by ObjectAnimator when setting the end values for an animation. - * The end values are set according to the current values in the target object. The - * property whose value is extracted is whatever is specified by the propertyName of this - * PropertyValuesHolder object. - * - * @param target The object which holds the start values that should be set. - */ - void setupEndValue(Object target) { - setupValue(target, mKeyframeSet.mKeyframes.get(mKeyframeSet.mKeyframes.size() - 1)); - } - - @Override - public PropertyValuesHolder clone() { - try { - PropertyValuesHolder newPVH = (PropertyValuesHolder) super.clone(); - newPVH.mPropertyName = mPropertyName; - //newPVH.mProperty = mProperty; - newPVH.mKeyframeSet = mKeyframeSet.clone(); - newPVH.mEvaluator = mEvaluator; - return newPVH; - } catch (CloneNotSupportedException e) { - // won't reach here - return null; - } - } - - /** - * 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 - */ - void setAnimatedValue(Object target) { - //if (mProperty != null) { - // mProperty.set(target, getAnimatedValue()); - //} - if (mSetter != null) { - try { - mTmpValueArray[0] = getAnimatedValue(); - mSetter.invoke(target, mTmpValueArray); - } catch (InvocationTargetException e) { - Log.e("PropertyValuesHolder", e.toString()); - } catch (IllegalAccessException e) { - Log.e("PropertyValuesHolder", e.toString()); - } - } - } - - /** - * Internal function, called by ValueAnimator, to set up the TypeEvaluator that will be used - * to calculate animated values. - */ - void init() { - if (mEvaluator == null) { - // We already handle int and float automatically, but not their Object - // equivalents - mEvaluator = (mValueType == Integer.class) ? sIntEvaluator : - (mValueType == Float.class) ? sFloatEvaluator : - null; - } - if (mEvaluator != null) { - // KeyframeSet knows how to evaluate the common types - only give it a custom - // evaluator if one has been set on this class - mKeyframeSet.setEvaluator(mEvaluator); - } - } - - /** - * The TypeEvaluator will the automatically determined based on the type of values - * supplied to PropertyValuesHolder. The evaluator can be manually set, however, if so - * desired. This may be important in cases where either the type of the values supplied - * do not match the way that they should be interpolated between, or if the values - * are of a custom type or one not currently understood by the animation system. Currently, - * only values of type float and int (and their Object equivalents: Float - * and Integer) are correctly interpolated; all other types require setting a TypeEvaluator. - * @param evaluator - */ - public void setEvaluator(TypeEvaluator evaluator) { - mEvaluator = evaluator; - mKeyframeSet.setEvaluator(evaluator); - } - - /** - * Function used to calculate the value according to the evaluator set up for - * this PropertyValuesHolder object. This function is called by ValueAnimator.animateValue(). - * - * @param fraction The elapsed, interpolated fraction of the animation. - */ - void calculateValue(float fraction) { - mAnimatedValue = mKeyframeSet.getValue(fraction); - } - - /** - * Sets the name of the property that will be animated. This name is used to derive - * a setter function that will be called to set animated values. - * For example, a property name of <code>foo</code> will result - * in a call to the function <code>setFoo()</code> on the target object. If either - * <code>valueFrom</code> or <code>valueTo</code> is null, then a getter function will - * also be derived and called. - * - * <p>Note that the setter function derived from this property name - * must take the same parameter type as the - * <code>valueFrom</code> and <code>valueTo</code> properties, otherwise the call to - * the setter function will fail.</p> - * - * @param propertyName The name of the property being animated. - */ - public void setPropertyName(String propertyName) { - mPropertyName = propertyName; - } - - /** - * Sets the property that will be animated. - * - * <p>Note that if this PropertyValuesHolder object is used with ObjectAnimator, the property - * must exist on the target object specified in that ObjectAnimator.</p> - * - * @param property The property being animated. - */ - //public void setProperty(Property property) { - // mProperty = property; - //} - - /** - * Gets the name of the property that will be animated. This name will be used to derive - * a setter function that will be called to set animated values. - * For example, a property name of <code>foo</code> will result - * in a call to the function <code>setFoo()</code> on the target object. If either - * <code>valueFrom</code> or <code>valueTo</code> is null, then a getter function will - * also be derived and called. - */ - public String getPropertyName() { - return mPropertyName; - } - - /** - * Internal function, called by ValueAnimator and ObjectAnimator, to retrieve the value - * most recently calculated in calculateValue(). - * @return - */ - Object getAnimatedValue() { - return mAnimatedValue; - } - - @Override - public String toString() { - return mPropertyName + ": " + mKeyframeSet.toString(); - } - - /** - * Utility method to derive a setter/getter method name from a property name, where the - * prefix is typically "set" or "get" and the first letter of the property name is - * capitalized. - * - * @param prefix The precursor to the method name, before the property name begins, typically - * "set" or "get". - * @param propertyName The name of the property that represents the bulk of the method name - * after the prefix. The first letter of this word will be capitalized in the resulting - * method name. - * @return String the property name converted to a method name according to the conventions - * specified above. - */ - static String getMethodName(String prefix, String propertyName) { - if (propertyName == null || propertyName.length() == 0) { - // shouldn't get here - return prefix; - } - char firstLetter = Character.toUpperCase(propertyName.charAt(0)); - String theRest = propertyName.substring(1); - return prefix + firstLetter + theRest; - } - - static class IntPropertyValuesHolder extends PropertyValuesHolder { - - // Cache JNI functions to avoid looking them up twice - //private static final HashMap<Class, HashMap<String, Integer>> sJNISetterPropertyMap = - // new HashMap<Class, HashMap<String, Integer>>(); - //int mJniSetter; - //private IntProperty mIntProperty; - - IntKeyframeSet mIntKeyframeSet; - int mIntAnimatedValue; - - public IntPropertyValuesHolder(String propertyName, IntKeyframeSet keyframeSet) { - super(propertyName); - mValueType = int.class; - mKeyframeSet = keyframeSet; - mIntKeyframeSet = (IntKeyframeSet) mKeyframeSet; - } - - //public IntPropertyValuesHolder(Property property, IntKeyframeSet keyframeSet) { - // super(property); - // mValueType = int.class; - // mKeyframeSet = keyframeSet; - // mIntKeyframeSet = (IntKeyframeSet) mKeyframeSet; - // if (property instanceof IntProperty) { - // mIntProperty = (IntProperty) mProperty; - // } - //} - - public IntPropertyValuesHolder(String propertyName, int... values) { - super(propertyName); - setIntValues(values); - } - - //public IntPropertyValuesHolder(Property property, int... values) { - // super(property); - // setIntValues(values); - // if (property instanceof IntProperty) { - // mIntProperty = (IntProperty) mProperty; - // } - //} - - @Override - public void setIntValues(int... values) { - super.setIntValues(values); - mIntKeyframeSet = (IntKeyframeSet) mKeyframeSet; - } - - @Override - void calculateValue(float fraction) { - mIntAnimatedValue = mIntKeyframeSet.getIntValue(fraction); - } - - @Override - Object getAnimatedValue() { - return mIntAnimatedValue; - } - - @Override - public IntPropertyValuesHolder clone() { - IntPropertyValuesHolder newPVH = (IntPropertyValuesHolder) super.clone(); - newPVH.mIntKeyframeSet = (IntKeyframeSet) newPVH.mKeyframeSet; - return newPVH; - } - - /** - * 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) { - //if (mIntProperty != null) { - // mIntProperty.setValue(target, mIntAnimatedValue); - // return; - //} - //if (mProperty != null) { - // mProperty.set(target, mIntAnimatedValue); - // return; - //} - //if (mJniSetter != 0) { - // nCallIntMethod(target, mJniSetter, mIntAnimatedValue); - // return; - //} - if (mSetter != null) { - try { - mTmpValueArray[0] = mIntAnimatedValue; - mSetter.invoke(target, mTmpValueArray); - } catch (InvocationTargetException e) { - Log.e("PropertyValuesHolder", e.toString()); - } catch (IllegalAccessException e) { - Log.e("PropertyValuesHolder", e.toString()); - } - } - } - - @Override - void setupSetter(Class targetClass) { - //if (mProperty != null) { - // return; - //} - // Check new static hashmap<propName, int> for setter method - //try { - // mPropertyMapLock.writeLock().lock(); - // HashMap<String, Integer> propertyMap = sJNISetterPropertyMap.get(targetClass); - // if (propertyMap != null) { - // Integer mJniSetterInteger = propertyMap.get(mPropertyName); - // if (mJniSetterInteger != null) { - // mJniSetter = mJniSetterInteger; - // } - // } - // if (mJniSetter == 0) { - // String methodName = getMethodName("set", mPropertyName); - // mJniSetter = nGetIntMethod(targetClass, methodName); - // if (mJniSetter != 0) { - // if (propertyMap == null) { - // propertyMap = new HashMap<String, Integer>(); - // sJNISetterPropertyMap.put(targetClass, propertyMap); - // } - // propertyMap.put(mPropertyName, mJniSetter); - // } - // } - //} catch (NoSuchMethodError e) { - // Log.d("PropertyValuesHolder", - // "Can't find native method using JNI, use reflection" + e); - //} finally { - // mPropertyMapLock.writeLock().unlock(); - //} - //if (mJniSetter == 0) { - // Couldn't find method through fast JNI approach - just use reflection - super.setupSetter(targetClass); - //} - } - } - - static class FloatPropertyValuesHolder extends PropertyValuesHolder { - - // Cache JNI functions to avoid looking them up twice - //private static final HashMap<Class, HashMap<String, Integer>> sJNISetterPropertyMap = - // new HashMap<Class, HashMap<String, Integer>>(); - //int mJniSetter; - //private FloatProperty mFloatProperty; - - FloatKeyframeSet mFloatKeyframeSet; - float mFloatAnimatedValue; - - public FloatPropertyValuesHolder(String propertyName, FloatKeyframeSet keyframeSet) { - super(propertyName); - mValueType = float.class; - mKeyframeSet = keyframeSet; - mFloatKeyframeSet = (FloatKeyframeSet) mKeyframeSet; - } - - //public FloatPropertyValuesHolder(Property property, FloatKeyframeSet keyframeSet) { - // super(property); - // mValueType = float.class; - // mKeyframeSet = keyframeSet; - // mFloatKeyframeSet = (FloatKeyframeSet) mKeyframeSet; - // if (property instanceof FloatProperty) { - // mFloatProperty = (FloatProperty) mProperty; - // } - //} - - public FloatPropertyValuesHolder(String propertyName, float... values) { - super(propertyName); - setFloatValues(values); - } - - //public FloatPropertyValuesHolder(Property property, float... values) { - // super(property); - // setFloatValues(values); - // if (property instanceof FloatProperty) { - // mFloatProperty = (FloatProperty) mProperty; - // } - //} - - @Override - public void setFloatValues(float... values) { - super.setFloatValues(values); - mFloatKeyframeSet = (FloatKeyframeSet) mKeyframeSet; - } - - @Override - void calculateValue(float fraction) { - mFloatAnimatedValue = mFloatKeyframeSet.getFloatValue(fraction); - } - - @Override - Object getAnimatedValue() { - return mFloatAnimatedValue; - } - - @Override - public FloatPropertyValuesHolder clone() { - FloatPropertyValuesHolder newPVH = (FloatPropertyValuesHolder) super.clone(); - newPVH.mFloatKeyframeSet = (FloatKeyframeSet) newPVH.mKeyframeSet; - return newPVH; - } - - /** - * 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) { - //if (mFloatProperty != null) { - // mFloatProperty.setValue(target, mFloatAnimatedValue); - // return; - //} - //if (mProperty != null) { - // mProperty.set(target, mFloatAnimatedValue); - // return; - //} - //if (mJniSetter != 0) { - // nCallFloatMethod(target, mJniSetter, mFloatAnimatedValue); - // return; - //} - if (mSetter != null) { - try { - mTmpValueArray[0] = mFloatAnimatedValue; - mSetter.invoke(target, mTmpValueArray); - } catch (InvocationTargetException e) { - Log.e("PropertyValuesHolder", e.toString()); - } catch (IllegalAccessException e) { - Log.e("PropertyValuesHolder", e.toString()); - } - } - } - - @Override - void setupSetter(Class targetClass) { - //if (mProperty != null) { - // return; - //} - // Check new static hashmap<propName, int> for setter method - //try { - // mPropertyMapLock.writeLock().lock(); - // HashMap<String, Integer> propertyMap = sJNISetterPropertyMap.get(targetClass); - // if (propertyMap != null) { - // Integer mJniSetterInteger = propertyMap.get(mPropertyName); - // if (mJniSetterInteger != null) { - // mJniSetter = mJniSetterInteger; - // } - // } - // if (mJniSetter == 0) { - // String methodName = getMethodName("set", mPropertyName); - // mJniSetter = nGetFloatMethod(targetClass, methodName); - // if (mJniSetter != 0) { - // if (propertyMap == null) { - // propertyMap = new HashMap<String, Integer>(); - // sJNISetterPropertyMap.put(targetClass, propertyMap); - // } - // propertyMap.put(mPropertyName, mJniSetter); - // } - // } - //} catch (NoSuchMethodError e) { - // Log.d("PropertyValuesHolder", - // "Can't find native method using JNI, use reflection" + e); - //} finally { - // mPropertyMapLock.writeLock().unlock(); - //} - //if (mJniSetter == 0) { - // Couldn't find method through fast JNI approach - just use reflection - super.setupSetter(targetClass); - //} - } - - } - - //native static private int nGetIntMethod(Class targetClass, String methodName); - //native static private int nGetFloatMethod(Class targetClass, String methodName); - //native static private void nCallIntMethod(Object target, int methodID, int arg); - //native static private void nCallFloatMethod(Object target, int methodID, float arg); -} |