/** * 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; }
@Override public FloatPropertyValuesHolder clone() { FloatPropertyValuesHolder newPVH = (FloatPropertyValuesHolder) super.clone(); newPVH.mFloatKeyframeSet = (FloatKeyframeSet) newPVH.mKeyframeSet; return newPVH; }
/** * The most recent value calculated by this <code>ValueAnimator</code> when there is just one * property being animated. This value is only sensible while the animation is running. The main * purpose for this read-only property is to retrieve the value from the <code>ValueAnimator</code> * during a call to {@link AnimatorUpdateListener#onAnimationUpdate(ValueAnimator)}, which * is called during each animation frame, immediately after the value is calculated. * * @return animatedValue The value most recently calculated by this <code>ValueAnimator</code> for * the single property being animated. If there are several properties being animated * (specified by several PropertyValuesHolder objects in the constructor), this function * returns the animated value for the first of those objects. */ public Object getAnimatedValue() { if (mValues != null && mValues.length > 0) { return mValues[0].getAnimatedValue(); } // Shouldn't get here; should always have values unless ValueAnimator was set up wrong return null; }
/** * Sets int values that will be animated between. A single * value implies that that value is the one being animated to. However, this is not typically * useful in a ValueAnimator object because there is no way for the object to determine the * starting value for the animation (unlike ObjectAnimator, which can derive that value * from the target object and property being animated). Therefore, there should typically * be two or more values. * * <p>If there are already multiple sets of values defined for this ValueAnimator via more * than one PropertyValuesHolder object, this method will set the values for the first * of those objects.</p> * * @param values A set of values that the animation will animate between over time. */ public void setIntValues(int... values) { if (values == null || values.length == 0) { return; } if (mValues == null || mValues.length == 0) { setValues(new PropertyValuesHolder[]{PropertyValuesHolder.ofInt("", values)}); } else { PropertyValuesHolder valuesHolder = mValues[0]; valuesHolder.setIntValues(values); } // New property/values/target should cause re-initialization prior to starting mInitialized = false; }
/** * Sets float values that will be animated between. A single * value implies that that value is the one being animated to. However, this is not typically * useful in a ValueAnimator object because there is no way for the object to determine the * starting value for the animation (unlike ObjectAnimator, which can derive that value * from the target object and property being animated). Therefore, there should typically * be two or more values. * * <p>If there are already multiple sets of values defined for this ValueAnimator via more * than one PropertyValuesHolder object, this method will set the values for the first * of those objects.</p> * * @param values A set of values that the animation will animate between over time. */ public void setFloatValues(float... values) { if (values == null || values.length == 0) { return; } if (mValues == null || mValues.length == 0) { setValues(new PropertyValuesHolder[]{PropertyValuesHolder.ofFloat("", values)}); } else { PropertyValuesHolder valuesHolder = mValues[0]; valuesHolder.setFloatValues(values); } // New property/values/target should cause re-initialization prior to starting mInitialized = false; }
@Override public ValueAnimator clone() { final ValueAnimator anim = (ValueAnimator) super.clone(); if (mUpdateListeners != null) { ArrayList<AnimatorUpdateListener> oldListeners = mUpdateListeners; anim.mUpdateListeners = new ArrayList<AnimatorUpdateListener>(); int numListeners = oldListeners.size(); for (int i = 0; i < numListeners; ++i) { anim.mUpdateListeners.add(oldListeners.get(i)); } } anim.mSeekTime = -1; anim.mPlayingBackwards = false; anim.mCurrentIteration = 0; anim.mInitialized = false; anim.mPlayingState = STOPPED; anim.mStartedDelay = false; PropertyValuesHolder[] oldValues = mValues; if (oldValues != null) { int numValues = oldValues.length; anim.mValues = new PropertyValuesHolder[numValues]; anim.mValuesMap = new HashMap<String, PropertyValuesHolder>(numValues); for (int i = 0; i < numValues; ++i) { PropertyValuesHolder newValuesHolder = oldValues[i].clone(); anim.mValues[i] = newValuesHolder; anim.mValuesMap.put(newValuesHolder.getPropertyName(), newValuesHolder); } } return anim; }
String oldName = valuesHolder.getPropertyName(); valuesHolder.setPropertyName(propertyName); mValuesMap.remove(oldName); mValuesMap.put(propertyName, valuesHolder);
/** * Sets the values, per property, being animated between. This function is called internally * by the constructors of ValueAnimator that take a list of values. But an ValueAnimator can * be constructed without values and this method can be called to set the values manually * instead. * * @param values The set of values, per property, being animated between. */ public void setValues(PropertyValuesHolder... values) { int numValues = values.length; mValues = values; mValuesMap = new HashMap<String, PropertyValuesHolder>(numValues); for (int i = 0; i < numValues; ++i) { PropertyValuesHolder valuesHolder = values[i]; mValuesMap.put(valuesHolder.getPropertyName(), valuesHolder); } // New property/values/target should cause re-initialization prior to starting mInitialized = false; }
@Override public void setIntValues(int... values) { if (mValues == null || mValues.length == 0) { // No values yet - this animator is being constructed piecemeal. Init the values with // whatever the current propertyName is //if (mProperty != null) { // setValues(PropertyValuesHolder.ofInt(mProperty, values)); //} else { setValues(PropertyValuesHolder.ofInt(mPropertyName, values)); //} } else { super.setIntValues(values); } }
@Override public void setFloatValues(float... values) { if (mValues == null || mValues.length == 0) { // No values yet - this animator is being constructed piecemeal. Init the values with // whatever the current propertyName is //if (mProperty != null) { // setValues(PropertyValuesHolder.ofFloat(mProperty, values)); //} else { setValues(PropertyValuesHolder.ofFloat(mPropertyName, values)); //} } else { super.setFloatValues(values); } }
/** * This function is called immediately before processing the first animation * frame of an animation. If there is a nonzero <code>startDelay</code>, the * function is called after that delay ends. * It takes care of the final initialization steps for the * animation. * * <p>Overrides of this method should call the superclass method to ensure * that internal mechanisms for the animation are set up correctly.</p> */ void initAnimation() { if (!mInitialized) { int numValues = mValues.length; for (int i = 0; i < numValues; ++i) { mValues[i].init(); } mInitialized = true; } }
/** * This method is called with the elapsed fraction of the animation during every * animation frame. This function turns the elapsed fraction into an interpolated fraction * and then into an animated value (from the evaluator. The function is called mostly during * animation updates, but it is also called when the <code>end()</code> * function is called, to set the final value on the property. * * <p>Overrides of this method must call the superclass to perform the calculation * of the animated value.</p> * * @param fraction The elapsed fraction of the animation. */ void animateValue(float fraction) { fraction = mInterpolator.getInterpolation(fraction); mCurrentFraction = fraction; int numValues = mValues.length; for (int i = 0; i < numValues; ++i) { mValues[i].calculateValue(fraction); } if (mUpdateListeners != null) { int numListeners = mUpdateListeners.size(); for (int i = 0; i < numListeners; ++i) { mUpdateListeners.get(i).onAnimationUpdate(this); } } }
PropertyValuesHolder pvh = new PropertyValuesHolder(propertyName); pvh.mKeyframeSet = keyframeSet; pvh.mValueType = values[0].getType();
setterOrGetter = getPropertyFunction(targetClass, prefix, valueType); if (propertyMap == null) { propertyMap = new HashMap<String, Method>();
String methodName = getMethodName(prefix, mPropertyName); Class args[] = null; if (valueType == null) {
/** * Sets int values that will be animated between. A single * value implies that that value is the one being animated to. However, this is not typically * useful in a ValueAnimator object because there is no way for the object to determine the * starting value for the animation (unlike ObjectAnimator, which can derive that value * from the target object and property being animated). Therefore, there should typically * be two or more values. * * <p>If there are already multiple sets of values defined for this ValueAnimator via more * than one PropertyValuesHolder object, this method will set the values for the first * of those objects.</p> * * @param values A set of values that the animation will animate between over time. */ public void setIntValues(int... values) { if (values == null || values.length == 0) { return; } if (mValues == null || mValues.length == 0) { setValues(new PropertyValuesHolder[]{PropertyValuesHolder.ofInt("", values)}); } else { PropertyValuesHolder valuesHolder = mValues[0]; valuesHolder.setIntValues(values); } // New property/values/target should cause re-initialization prior to starting mInitialized = false; }
/** * Sets float values that will be animated between. A single * value implies that that value is the one being animated to. However, this is not typically * useful in a ValueAnimator object because there is no way for the object to determine the * starting value for the animation (unlike ObjectAnimator, which can derive that value * from the target object and property being animated). Therefore, there should typically * be two or more values. * * <p>If there are already multiple sets of values defined for this ValueAnimator via more * than one PropertyValuesHolder object, this method will set the values for the first * of those objects.</p> * * @param values A set of values that the animation will animate between over time. */ public void setFloatValues(float... values) { if (values == null || values.length == 0) { return; } if (mValues == null || mValues.length == 0) { setValues(new PropertyValuesHolder[]{PropertyValuesHolder.ofFloat("", values)}); } else { PropertyValuesHolder valuesHolder = mValues[0]; valuesHolder.setFloatValues(values); } // New property/values/target should cause re-initialization prior to starting mInitialized = false; }
@Override public ValueAnimator clone() { final ValueAnimator anim = (ValueAnimator) super.clone(); if (mUpdateListeners != null) { ArrayList<AnimatorUpdateListener> oldListeners = mUpdateListeners; anim.mUpdateListeners = new ArrayList<AnimatorUpdateListener>(); int numListeners = oldListeners.size(); for (int i = 0; i < numListeners; ++i) { anim.mUpdateListeners.add(oldListeners.get(i)); } } anim.mSeekTime = -1; anim.mPlayingBackwards = false; anim.mCurrentIteration = 0; anim.mInitialized = false; anim.mPlayingState = STOPPED; anim.mStartedDelay = false; PropertyValuesHolder[] oldValues = mValues; if (oldValues != null) { int numValues = oldValues.length; anim.mValues = new PropertyValuesHolder[numValues]; anim.mValuesMap = new HashMap<String, PropertyValuesHolder>(numValues); for (int i = 0; i < numValues; ++i) { PropertyValuesHolder newValuesHolder = oldValues[i].clone(); anim.mValues[i] = newValuesHolder; anim.mValuesMap.put(newValuesHolder.getPropertyName(), newValuesHolder); } } return anim; }
String oldName = valuesHolder.getPropertyName(); valuesHolder.setPropertyName(propertyName); mValuesMap.remove(oldName); mValuesMap.put(propertyName, valuesHolder);
/** * Sets the values, per property, being animated between. This function is called internally * by the constructors of ValueAnimator that take a list of values. But an ValueAnimator can * be constructed without values and this method can be called to set the values manually * instead. * * @param values The set of values, per property, being animated between. */ public void setValues(PropertyValuesHolder... values) { int numValues = values.length; mValues = values; mValuesMap = new HashMap<String, PropertyValuesHolder>(numValues); for (int i = 0; i < numValues; ++i) { PropertyValuesHolder valuesHolder = values[i]; mValuesMap.put(valuesHolder.getPropertyName(), valuesHolder); } // New property/values/target should cause re-initialization prior to starting mInitialized = false; }