Merge branch 'master' of ssh://android-git:29418/platform/frameworks/base
This commit is contained in:
230
api/current.xml
230
api/current.xml
@@ -19952,63 +19952,7 @@
|
||||
>
|
||||
<parameter name="duration" type="long">
|
||||
</parameter>
|
||||
<parameter name="keyframes" type="android.animation.Keyframe...">
|
||||
</parameter>
|
||||
</constructor>
|
||||
<constructor name="Animator"
|
||||
type="android.animation.Animator"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
<parameter name="duration" type="long">
|
||||
</parameter>
|
||||
<parameter name="valueFrom" type="float">
|
||||
</parameter>
|
||||
<parameter name="valueTo" type="float">
|
||||
</parameter>
|
||||
</constructor>
|
||||
<constructor name="Animator"
|
||||
type="android.animation.Animator"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
<parameter name="duration" type="long">
|
||||
</parameter>
|
||||
<parameter name="valueFrom" type="int">
|
||||
</parameter>
|
||||
<parameter name="valueTo" type="int">
|
||||
</parameter>
|
||||
</constructor>
|
||||
<constructor name="Animator"
|
||||
type="android.animation.Animator"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
<parameter name="duration" type="long">
|
||||
</parameter>
|
||||
<parameter name="valueFrom" type="double">
|
||||
</parameter>
|
||||
<parameter name="valueTo" type="double">
|
||||
</parameter>
|
||||
</constructor>
|
||||
<constructor name="Animator"
|
||||
type="android.animation.Animator"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
<parameter name="duration" type="long">
|
||||
</parameter>
|
||||
<parameter name="valueFrom" type="java.lang.Object">
|
||||
</parameter>
|
||||
<parameter name="valueTo" type="java.lang.Object">
|
||||
<parameter name="values" type="T...">
|
||||
</parameter>
|
||||
</constructor>
|
||||
<method name="addUpdateListener"
|
||||
@@ -20035,6 +19979,19 @@
|
||||
visibility="public"
|
||||
>
|
||||
</method>
|
||||
<method name="getAnimatedValue"
|
||||
return="java.lang.Object"
|
||||
abstract="false"
|
||||
native="false"
|
||||
synchronized="false"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
<parameter name="propertyName" type="java.lang.String">
|
||||
</parameter>
|
||||
</method>
|
||||
<method name="getCurrentPlayTime"
|
||||
return="long"
|
||||
abstract="false"
|
||||
@@ -20090,28 +20047,6 @@
|
||||
visibility="public"
|
||||
>
|
||||
</method>
|
||||
<method name="getValueFrom"
|
||||
return="java.lang.Object"
|
||||
abstract="false"
|
||||
native="false"
|
||||
synchronized="false"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
</method>
|
||||
<method name="getValueTo"
|
||||
return="java.lang.Object"
|
||||
abstract="false"
|
||||
native="false"
|
||||
synchronized="false"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
</method>
|
||||
<method name="isRunning"
|
||||
return="boolean"
|
||||
abstract="false"
|
||||
@@ -20238,7 +20173,7 @@
|
||||
<parameter name="startDelay" type="long">
|
||||
</parameter>
|
||||
</method>
|
||||
<method name="setValueFrom"
|
||||
<method name="setValues"
|
||||
return="void"
|
||||
abstract="false"
|
||||
native="false"
|
||||
@@ -20248,10 +20183,10 @@
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
<parameter name="valueFrom" type="java.lang.Object">
|
||||
<parameter name="values" type="android.animation.PropertyValuesHolder...">
|
||||
</parameter>
|
||||
</method>
|
||||
<method name="setValueTo"
|
||||
<method name="setValues"
|
||||
return="void"
|
||||
abstract="false"
|
||||
native="false"
|
||||
@@ -20261,7 +20196,7 @@
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
<parameter name="valueTo" type="java.lang.Object">
|
||||
<parameter name="values" type="T...">
|
||||
</parameter>
|
||||
</method>
|
||||
<field name="INFINITE"
|
||||
@@ -20594,15 +20529,13 @@
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
<parameter name="duration" type="int">
|
||||
<parameter name="duration" type="long">
|
||||
</parameter>
|
||||
<parameter name="target" type="java.lang.Object">
|
||||
</parameter>
|
||||
<parameter name="propertyName" type="java.lang.String">
|
||||
</parameter>
|
||||
<parameter name="valueFrom" type="float">
|
||||
</parameter>
|
||||
<parameter name="valueTo" type="float">
|
||||
<parameter name="values" type="T...">
|
||||
</parameter>
|
||||
</constructor>
|
||||
<constructor name="PropertyAnimator"
|
||||
@@ -20612,131 +20545,90 @@
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
<parameter name="duration" type="int">
|
||||
<parameter name="duration" type="long">
|
||||
</parameter>
|
||||
<parameter name="target" type="java.lang.Object">
|
||||
</parameter>
|
||||
<parameter name="propertyName" type="java.lang.String">
|
||||
</parameter>
|
||||
<parameter name="valueTo" type="float">
|
||||
<parameter name="values" type="android.animation.PropertyValuesHolder...">
|
||||
</parameter>
|
||||
</constructor>
|
||||
<constructor name="PropertyAnimator"
|
||||
type="android.animation.PropertyAnimator"
|
||||
<method name="getPropertyName"
|
||||
return="java.lang.String"
|
||||
abstract="false"
|
||||
native="false"
|
||||
synchronized="false"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
<parameter name="duration" type="int">
|
||||
</parameter>
|
||||
<parameter name="target" type="java.lang.Object">
|
||||
</parameter>
|
||||
<parameter name="propertyName" type="java.lang.String">
|
||||
</parameter>
|
||||
<parameter name="valueFrom" type="int">
|
||||
</parameter>
|
||||
<parameter name="valueTo" type="int">
|
||||
</parameter>
|
||||
</constructor>
|
||||
<constructor name="PropertyAnimator"
|
||||
type="android.animation.PropertyAnimator"
|
||||
</method>
|
||||
<method name="getTarget"
|
||||
return="java.lang.Object"
|
||||
abstract="false"
|
||||
native="false"
|
||||
synchronized="false"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
<parameter name="duration" type="int">
|
||||
</parameter>
|
||||
<parameter name="target" type="java.lang.Object">
|
||||
</parameter>
|
||||
<parameter name="propertyName" type="java.lang.String">
|
||||
</parameter>
|
||||
<parameter name="valueTo" type="int">
|
||||
</parameter>
|
||||
</constructor>
|
||||
<constructor name="PropertyAnimator"
|
||||
type="android.animation.PropertyAnimator"
|
||||
</method>
|
||||
<method name="setPropertyName"
|
||||
return="void"
|
||||
abstract="false"
|
||||
native="false"
|
||||
synchronized="false"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
<parameter name="duration" type="int">
|
||||
</parameter>
|
||||
<parameter name="target" type="java.lang.Object">
|
||||
</parameter>
|
||||
<parameter name="propertyName" type="java.lang.String">
|
||||
</parameter>
|
||||
<parameter name="valueFrom" type="double">
|
||||
</parameter>
|
||||
<parameter name="valueTo" type="double">
|
||||
</parameter>
|
||||
</constructor>
|
||||
<constructor name="PropertyAnimator"
|
||||
type="android.animation.PropertyAnimator"
|
||||
</method>
|
||||
<method name="setTarget"
|
||||
return="void"
|
||||
abstract="false"
|
||||
native="false"
|
||||
synchronized="false"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
<parameter name="duration" type="int">
|
||||
</parameter>
|
||||
<parameter name="target" type="java.lang.Object">
|
||||
</parameter>
|
||||
<parameter name="propertyName" type="java.lang.String">
|
||||
</parameter>
|
||||
<parameter name="valueTo" type="double">
|
||||
</parameter>
|
||||
</constructor>
|
||||
<constructor name="PropertyAnimator"
|
||||
type="android.animation.PropertyAnimator"
|
||||
</method>
|
||||
</class>
|
||||
<class name="PropertyValuesHolder"
|
||||
extends="java.lang.Object"
|
||||
abstract="false"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
<parameter name="duration" type="int">
|
||||
</parameter>
|
||||
<parameter name="target" type="java.lang.Object">
|
||||
</parameter>
|
||||
<parameter name="propertyName" type="java.lang.String">
|
||||
</parameter>
|
||||
<parameter name="valueFrom" type="java.lang.Object">
|
||||
</parameter>
|
||||
<parameter name="valueTo" type="java.lang.Object">
|
||||
</parameter>
|
||||
</constructor>
|
||||
<constructor name="PropertyAnimator"
|
||||
type="android.animation.PropertyAnimator"
|
||||
<constructor name="PropertyValuesHolder"
|
||||
type="android.animation.PropertyValuesHolder"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
<parameter name="duration" type="int">
|
||||
</parameter>
|
||||
<parameter name="target" type="java.lang.Object">
|
||||
</parameter>
|
||||
<parameter name="propertyName" type="java.lang.String">
|
||||
</parameter>
|
||||
<parameter name="valueTo" type="java.lang.Object">
|
||||
<parameter name="values" type="T...">
|
||||
</parameter>
|
||||
</constructor>
|
||||
<constructor name="PropertyAnimator"
|
||||
type="android.animation.PropertyAnimator"
|
||||
<constructor name="PropertyValuesHolder"
|
||||
type="android.animation.PropertyValuesHolder"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
<parameter name="duration" type="int">
|
||||
</parameter>
|
||||
<parameter name="target" type="java.lang.Object">
|
||||
</parameter>
|
||||
<parameter name="propertyName" type="java.lang.String">
|
||||
</parameter>
|
||||
<parameter name="keyframes" type="android.animation.Keyframe...">
|
||||
<parameter name="values" type="T...">
|
||||
</parameter>
|
||||
</constructor>
|
||||
<method name="getGetter"
|
||||
@@ -20772,8 +20664,8 @@
|
||||
visibility="public"
|
||||
>
|
||||
</method>
|
||||
<method name="getTarget"
|
||||
return="java.lang.Object"
|
||||
<method name="setEvaluator"
|
||||
return="void"
|
||||
abstract="false"
|
||||
native="false"
|
||||
synchronized="false"
|
||||
@@ -20782,6 +20674,8 @@
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
<parameter name="evaluator" type="android.animation.TypeEvaluator">
|
||||
</parameter>
|
||||
</method>
|
||||
<method name="setGetter"
|
||||
return="void"
|
||||
@@ -20822,7 +20716,7 @@
|
||||
<parameter name="setter" type="java.lang.reflect.Method">
|
||||
</parameter>
|
||||
</method>
|
||||
<method name="setTarget"
|
||||
<method name="setValues"
|
||||
return="void"
|
||||
abstract="false"
|
||||
native="false"
|
||||
@@ -20832,7 +20726,7 @@
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
<parameter name="target" type="java.lang.Object">
|
||||
<parameter name="values" type="T...">
|
||||
</parameter>
|
||||
</method>
|
||||
</class>
|
||||
|
||||
@@ -26,6 +26,7 @@ import android.view.animation.AnimationUtils;
|
||||
import android.view.animation.Interpolator;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
||||
/**
|
||||
* This class provides a simple timing engine for running animations
|
||||
@@ -39,7 +40,7 @@ import java.util.ArrayList;
|
||||
* out of an animation. This behavior can be changed by calling
|
||||
* {@link Animator#setInterpolator(Interpolator)}.</p>
|
||||
*/
|
||||
public class Animator extends Animatable {
|
||||
public class Animator<T> extends Animatable {
|
||||
|
||||
/**
|
||||
* Internal constants
|
||||
@@ -164,12 +165,6 @@ public class Animator extends Animatable {
|
||||
// How long the animation should last in ms
|
||||
private long mDuration;
|
||||
|
||||
// The value that the animation should start from, set in the constructor
|
||||
private Object mValueFrom;
|
||||
|
||||
// The value that the animation should animate to, set in the constructor
|
||||
private Object mValueTo;
|
||||
|
||||
// The amount of time in ms to delay starting the animation after start() is called
|
||||
private long mStartDelay = 0;
|
||||
|
||||
@@ -194,30 +189,23 @@ public class Animator extends Animatable {
|
||||
*/
|
||||
private Interpolator mInterpolator = sDefaultInterpolator;
|
||||
|
||||
/**
|
||||
* 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, double, and float. Any other
|
||||
* type will need to set the evaluator to a custom evaluator for that type.
|
||||
*/
|
||||
private TypeEvaluator mEvaluator;
|
||||
|
||||
/**
|
||||
* The set of listeners to be sent events through the life of an animation.
|
||||
*/
|
||||
private ArrayList<AnimatorUpdateListener> mUpdateListeners = null;
|
||||
|
||||
/**
|
||||
* The current value calculated by the animation. The value is calculated in animateFraction(),
|
||||
* prior to calling the setter (if set) and sending out the onAnimationUpdate() callback
|
||||
* to the update listeners.
|
||||
* The property/value sets being animated.
|
||||
*/
|
||||
private Object mAnimatedValue = null;
|
||||
HashMap<String, PropertyValuesHolder> mValues;
|
||||
|
||||
/**
|
||||
* The set of keyframes (time/value pairs) that define this animation.
|
||||
* This value is used in the simple/common case of animating just one value; the user
|
||||
* may call getAnimatedValue(), which should return the value of the first (and only)
|
||||
* ProeprtyValuesHolder animated value, which is looked up using this string.
|
||||
*/
|
||||
private KeyframeSet mKeyframeSet = null;
|
||||
String mFirstPropertyName;
|
||||
|
||||
|
||||
/**
|
||||
* The type of the values, as determined by the valueFrom/valueTo properties.
|
||||
@@ -267,144 +255,120 @@ public class Animator extends Animatable {
|
||||
int valueType = a.getInt(com.android.internal.R.styleable.Animator_valueType,
|
||||
VALUE_TYPE_FLOAT);
|
||||
|
||||
Object valueFrom = null;
|
||||
Object valueTo = null;
|
||||
|
||||
switch (valueType) {
|
||||
case VALUE_TYPE_FLOAT:
|
||||
mValueFrom = a.getFloat(com.android.internal.R.styleable.Animator_valueFrom, 0f);
|
||||
mValueTo = a.getFloat(com.android.internal.R.styleable.Animator_valueTo, 0f);
|
||||
valueFrom = a.getFloat(com.android.internal.R.styleable.Animator_valueFrom, 0f);
|
||||
valueTo = a.getFloat(com.android.internal.R.styleable.Animator_valueTo, 0f);
|
||||
mValueType = float.class;
|
||||
break;
|
||||
case VALUE_TYPE_INT:
|
||||
mValueFrom = a.getInt(com.android.internal.R.styleable.Animator_valueFrom, 0);
|
||||
mValueTo = a.getInt(com.android.internal.R.styleable.Animator_valueTo, 0);
|
||||
valueFrom = a.getInt(com.android.internal.R.styleable.Animator_valueFrom, 0);
|
||||
valueTo = a.getInt(com.android.internal.R.styleable.Animator_valueTo, 0);
|
||||
mValueType = int.class;
|
||||
break;
|
||||
case VALUE_TYPE_DOUBLE:
|
||||
mValueFrom = (double)
|
||||
valueFrom = (double)
|
||||
a.getFloat(com.android.internal.R.styleable.Animator_valueFrom, 0f);
|
||||
mValueTo = (double)
|
||||
valueTo = (double)
|
||||
a.getFloat(com.android.internal.R.styleable.Animator_valueTo, 0f);
|
||||
mValueType = double.class;
|
||||
break;
|
||||
case VALUE_TYPE_COLOR:
|
||||
mValueFrom = a.getInt(com.android.internal.R.styleable.Animator_valueFrom, 0);
|
||||
mValueTo = a.getInt(com.android.internal.R.styleable.Animator_valueTo, 0);
|
||||
mEvaluator = new RGBEvaluator();
|
||||
valueFrom = a.getInt(com.android.internal.R.styleable.Animator_valueFrom, 0);
|
||||
valueTo = a.getInt(com.android.internal.R.styleable.Animator_valueTo, 0);
|
||||
setEvaluator(new RGBEvaluator());
|
||||
mValueType = int.class;
|
||||
break;
|
||||
case VALUE_TYPE_CUSTOM:
|
||||
// TODO: How to get an 'Object' value?
|
||||
mValueFrom = a.getFloat(com.android.internal.R.styleable.Animator_valueFrom, 0f);
|
||||
mValueTo = a.getFloat(com.android.internal.R.styleable.Animator_valueTo, 0f);
|
||||
valueFrom = a.getFloat(com.android.internal.R.styleable.Animator_valueFrom, 0f);
|
||||
valueTo = a.getFloat(com.android.internal.R.styleable.Animator_valueTo, 0f);
|
||||
mValueType = Object.class;
|
||||
break;
|
||||
}
|
||||
|
||||
mValues = new HashMap<String, PropertyValuesHolder>(1);
|
||||
mFirstPropertyName = "";
|
||||
PropertyValuesHolder valuesHolder = new PropertyValuesHolder(mFirstPropertyName,
|
||||
valueFrom, valueTo);
|
||||
mValues.put(mFirstPropertyName, valuesHolder);
|
||||
|
||||
mRepeatCount = a.getInt(com.android.internal.R.styleable.Animator_repeatCount, mRepeatCount);
|
||||
mRepeatMode = a.getInt(com.android.internal.R.styleable.Animator_repeatMode, RESTART);
|
||||
|
||||
a.recycle();
|
||||
}
|
||||
|
||||
private Animator(long duration, Object valueFrom, Object valueTo, Class valueType) {
|
||||
|
||||
/**
|
||||
* Constructs an Animator object with the specified duration and set of
|
||||
* values. If the values are a set of PropertyValuesHolder objects, then these objects
|
||||
* define the potentially multiple properties being animated and the values the properties are
|
||||
* animated between. Otherwise, the values define a single set of values animated between.
|
||||
*
|
||||
* @param duration The length of the animation, in milliseconds.
|
||||
* @param values The set of values to animate between. If these values are not
|
||||
* PropertyValuesHolder objects, then there should be more than one value, since the values
|
||||
* determine the interval to animate between.
|
||||
*/
|
||||
public Animator(long duration, T...values) {
|
||||
mDuration = duration;
|
||||
mValueFrom = valueFrom;
|
||||
mValueTo= valueTo;
|
||||
this.mValueType = valueType;
|
||||
if (values.length > 0) {
|
||||
setValues(values);
|
||||
}
|
||||
}
|
||||
|
||||
public void setValues(PropertyValuesHolder... values) {
|
||||
int numValues = values.length;
|
||||
mValues = new HashMap<String, PropertyValuesHolder>(numValues);
|
||||
for (int i = 0; i < numValues; ++i) {
|
||||
PropertyValuesHolder valuesHolder = (PropertyValuesHolder) values[i];
|
||||
mValues.put(valuesHolder.getPropertyName(), valuesHolder);
|
||||
}
|
||||
if (numValues > 0 && values[0] != null) {
|
||||
mFirstPropertyName = ((PropertyValuesHolder) values[0]).getPropertyName();
|
||||
} else {
|
||||
mFirstPropertyName = "";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This constructor takes a set of {@link Keyframe} objects that define the values
|
||||
* for the animation, along with the times at which those values will hold true during
|
||||
* the animation.
|
||||
* Sets the values to animate between for this animation. If <code>values</code> is
|
||||
* a set of PropertyValuesHolder objects, these objects will become the set of properties
|
||||
* animated and the values that those properties are animated between. Otherwise, this method
|
||||
* will set only one set of values for the Animator. Also, if the values are not
|
||||
* PropertyValuesHolder objects and if there are already multiple sets of
|
||||
* values defined for this Animator via
|
||||
* more than one PropertyValuesHolder objects, this method will set the values for
|
||||
* the first of those objects.
|
||||
*
|
||||
* @param duration The length of the animation, in milliseconds.
|
||||
* @param keyframes The set of keyframes that define the time/value pairs for the animation.
|
||||
* @param values The set of values to animate between.
|
||||
*/
|
||||
public Animator(long duration, Keyframe...keyframes) {
|
||||
mDuration = duration;
|
||||
mKeyframeSet = new KeyframeSet(keyframes);
|
||||
mValueType = keyframes[0].getType();
|
||||
}
|
||||
|
||||
/**
|
||||
* A constructor that takes <code>float</code> values.
|
||||
*
|
||||
* @param duration The length of the animation, in milliseconds.
|
||||
* @param valueFrom The initial value of the property when the animation begins.
|
||||
* @param valueTo The value to which the property will animate.
|
||||
*/
|
||||
public Animator(long duration, float valueFrom, float valueTo) {
|
||||
this(duration, valueFrom, valueTo, float.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* A constructor that takes <code>int</code> values.
|
||||
*
|
||||
* @param duration The length of the animation, in milliseconds.
|
||||
* @param valueFrom The initial value of the property when the animation begins.
|
||||
* @param valueTo The value to which the property will animate.
|
||||
*/
|
||||
public Animator(long duration, int valueFrom, int valueTo) {
|
||||
this(duration, valueFrom, valueTo, int.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* A constructor that takes <code>double</code> values.
|
||||
*
|
||||
* @param duration The length of the animation, in milliseconds.
|
||||
* @param valueFrom The initial value of the property when the animation begins.
|
||||
* @param valueTo The value to which the property will animate.
|
||||
*/
|
||||
public Animator(long duration, double valueFrom, double valueTo) {
|
||||
this(duration, valueFrom, valueTo, double.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* A constructor that takes <code>Object</code> values.
|
||||
*
|
||||
* @param duration The length of the animation, in milliseconds.
|
||||
* @param valueFrom The initial value of the property when the animation begins.
|
||||
* @param valueTo The value to which the property will animate.
|
||||
*/
|
||||
public Animator(long duration, Object valueFrom, Object valueTo) {
|
||||
this(duration, valueFrom, valueTo,
|
||||
(valueFrom != null) ? valueFrom.getClass() : valueTo.getClass());
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal constructor that takes a single <code>float</code> value.
|
||||
* This constructor is called by PropertyAnimator.
|
||||
*
|
||||
* @param duration The length of the animation, in milliseconds.
|
||||
* @param valueFrom The initial value of the property when the animation begins.
|
||||
* @param valueTo The value to which the property will animate.
|
||||
*/
|
||||
Animator(long duration, float valueTo) {
|
||||
this(duration, null, valueTo, float.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal constructor that takes a single <code>int</code> value.
|
||||
* This constructor is called by PropertyAnimator.
|
||||
*
|
||||
* @param duration The length of the animation, in milliseconds.
|
||||
* @param valueFrom The initial value of the property when the animation begins.
|
||||
* @param valueTo The value to which the property will animate.
|
||||
*/
|
||||
Animator(long duration, int valueTo) {
|
||||
this(duration, null, valueTo, int.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal constructor that takes a single <code>double</code> value.
|
||||
* This constructor is called by PropertyAnimator.
|
||||
*
|
||||
* @param duration The length of the animation, in milliseconds.
|
||||
* @param valueFrom The initial value of the property when the animation begins.
|
||||
* @param valueTo The value to which the property will animate.
|
||||
*/
|
||||
Animator(long duration, double valueTo) {
|
||||
this(duration, null, valueTo, double.class);
|
||||
public void setValues(T... values) {
|
||||
if (values[0] instanceof PropertyValuesHolder) {
|
||||
int numValues = values.length;
|
||||
mValues = new HashMap<String, PropertyValuesHolder>(numValues);
|
||||
for (int i = 0; i < numValues; ++i) {
|
||||
PropertyValuesHolder valuesHolder = (PropertyValuesHolder) values[i];
|
||||
mValues.put(valuesHolder.getPropertyName(), valuesHolder);
|
||||
}
|
||||
if (numValues > 0 && values[0] != null) {
|
||||
mFirstPropertyName = ((PropertyValuesHolder) values[0]).getPropertyName();
|
||||
} else {
|
||||
mFirstPropertyName = "";
|
||||
}
|
||||
} else {
|
||||
if (mValues == null) {
|
||||
setValues(new PropertyValuesHolder[]{
|
||||
new PropertyValuesHolder("", (Object[])values)});
|
||||
} else {
|
||||
PropertyValuesHolder valuesHolder = mValues.get(mFirstPropertyName);
|
||||
valuesHolder.setValues(values);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -418,9 +382,8 @@ public class Animator extends Animatable {
|
||||
* that internal mechanisms for the animation are set up correctly.</p>
|
||||
*/
|
||||
void initAnimation() {
|
||||
if (mEvaluator == null) {
|
||||
mEvaluator = (mValueType == int.class) ? sIntEvaluator :
|
||||
(mValueType == double.class) ? sDoubleEvaluator : sFloatEvaluator;
|
||||
for (PropertyValuesHolder pvHolder: mValues.values()) {
|
||||
pvHolder.init();
|
||||
}
|
||||
mCurrentIteration = 0;
|
||||
mInitialized = true;
|
||||
@@ -598,67 +561,6 @@ public class Animator extends Animatable {
|
||||
return sFrameDelay;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the set of keyframes that define this animation.
|
||||
*
|
||||
* @return KeyframeSet The set of keyframes for this animation.
|
||||
*/
|
||||
KeyframeSet getKeyframes() {
|
||||
return mKeyframeSet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value that this animation will start from.
|
||||
*
|
||||
* @return Object The starting value for the animation.
|
||||
*/
|
||||
public Object getValueFrom() {
|
||||
if (mKeyframeSet != null) {
|
||||
return mKeyframeSet.mKeyframes.get(0).getValue();
|
||||
}
|
||||
return mValueFrom;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value that this animation will start from.
|
||||
*/
|
||||
public void setValueFrom(Object valueFrom) {
|
||||
if (mKeyframeSet != null) {
|
||||
Keyframe kf = mKeyframeSet.mKeyframes.get(0);
|
||||
kf.setValue(valueFrom);
|
||||
} else {
|
||||
mValueFrom = valueFrom;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value that this animation will animate to.
|
||||
*
|
||||
* @return Object The ending value for the animation.
|
||||
*/
|
||||
public Object getValueTo() {
|
||||
if (mKeyframeSet != null) {
|
||||
int numKeyframes = mKeyframeSet.mKeyframes.size();
|
||||
return mKeyframeSet.mKeyframes.get(numKeyframes - 1).getValue();
|
||||
}
|
||||
return mValueTo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value that this animation will animate to.
|
||||
*
|
||||
* @return Object The ending value for the animation.
|
||||
*/
|
||||
public void setValueTo(Object valueTo) {
|
||||
if (mKeyframeSet != null) {
|
||||
int numKeyframes = mKeyframeSet.mKeyframes.size();
|
||||
Keyframe kf = mKeyframeSet.mKeyframes.get(numKeyframes - 1);
|
||||
kf.setValue(valueTo);
|
||||
} else {
|
||||
mValueTo = valueTo;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The amount of time, in milliseconds, between each frame of the animation. This is a
|
||||
* requested time that the animation will attempt to honor, but the actual delay between
|
||||
@@ -673,17 +575,33 @@ public class Animator extends Animatable {
|
||||
}
|
||||
|
||||
/**
|
||||
* The most recent value calculated by this <code>Animator</code> for the property
|
||||
* being animated. This value is only sensible while the animation is running. The main
|
||||
* The most recent value calculated by this <code>Animator</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>Animator</code>
|
||||
* during a call to {@link AnimatorUpdateListener#onAnimationUpdate(Animator)}, which
|
||||
* is called during each animation frame, immediately after the value is calculated.
|
||||
*
|
||||
* @return animatedValue The value most recently calculated by this <code>Animator</code> for
|
||||
* the property specified in the constructor.
|
||||
* 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() {
|
||||
return mAnimatedValue;
|
||||
return getAnimatedValue(mFirstPropertyName);
|
||||
}
|
||||
|
||||
/**
|
||||
* The most recent value calculated by this <code>Animator</code> for <code>propertyName</code>.
|
||||
* The main purpose for this read-only property is to retrieve the value from the
|
||||
* <code>Animator</code> during a call to
|
||||
* {@link AnimatorUpdateListener#onAnimationUpdate(Animator)}, which
|
||||
* is called during each animation frame, immediately after the value is calculated.
|
||||
*
|
||||
* @return animatedValue The value most recently calculated for the named property
|
||||
* by this <code>Animator</code>.
|
||||
*/
|
||||
public Object getAnimatedValue(String propertyName) {
|
||||
return mValues.get(mFirstPropertyName).getAnimatedValue();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -781,14 +699,26 @@ public class Animator extends Animatable {
|
||||
* For example, when running an animation on color values, the {@link RGBEvaluator}
|
||||
* should be used to get correct RGB color interpolation.
|
||||
*
|
||||
* <p>If this Animator has only one set of values being animated between, this evaluator
|
||||
* will be used for that set. If there are several sets of values being animated, which is
|
||||
* the case if PropertyValuesHOlder objects were set on the Animator, then the evaluator
|
||||
* is assigned just to the first PropertyValuesHolder object.</p>
|
||||
*
|
||||
* @param value the evaluator to be used this animation
|
||||
*/
|
||||
public void setEvaluator(TypeEvaluator value) {
|
||||
if (value != null) {
|
||||
mEvaluator = value;
|
||||
if (value != null && mValues != null) {
|
||||
mValues.get(mFirstPropertyName).setEvaluator(value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Start the animation playing. This version of start() takes a boolean flag that indicates
|
||||
* whether the animation should play in reverse. The flag is usually false, but may be set
|
||||
* to true if called from the reverse() method/
|
||||
*
|
||||
* @param playBackwards Whether the Animator should start playing in reverse.
|
||||
*/
|
||||
private void start(boolean playBackwards) {
|
||||
mPlayingBackwards = playBackwards;
|
||||
mPlayingState = STOPPED;
|
||||
@@ -998,10 +928,8 @@ public class Animator extends Animatable {
|
||||
*/
|
||||
void animateValue(float fraction) {
|
||||
fraction = mInterpolator.getInterpolation(fraction);
|
||||
if (mKeyframeSet != null) {
|
||||
mAnimatedValue = mKeyframeSet.getValue(fraction, mEvaluator);
|
||||
} else {
|
||||
mAnimatedValue = mEvaluator.evaluate(fraction, mValueFrom, mValueTo);
|
||||
for (PropertyValuesHolder valuesHolder : mValues.values()) {
|
||||
valuesHolder.calculateValue(fraction);
|
||||
}
|
||||
if (mUpdateListeners != null) {
|
||||
int numListeners = mUpdateListeners.size();
|
||||
|
||||
@@ -36,7 +36,7 @@ public class DoubleEvaluator implements TypeEvaluator {
|
||||
* <code>fraction</code> parameter.
|
||||
*/
|
||||
public Object evaluate(float fraction, Object startValue, Object endValue) {
|
||||
double startDouble = (Double) startValue;
|
||||
return startDouble + fraction * ((Double) endValue - startDouble);
|
||||
double startDouble = ((Number) startValue).doubleValue();
|
||||
return startDouble + fraction * (((Number) endValue).doubleValue() - startDouble);
|
||||
}
|
||||
}
|
||||
@@ -36,7 +36,7 @@ public class FloatEvaluator implements TypeEvaluator {
|
||||
* <code>fraction</code> parameter.
|
||||
*/
|
||||
public Object evaluate(float fraction, Object startValue, Object endValue) {
|
||||
float startFloat = (Float) startValue;
|
||||
return startFloat + fraction * ((Float) endValue - startFloat);
|
||||
float startFloat = ((Number) startValue).floatValue();
|
||||
return startFloat + fraction * (((Number) endValue).floatValue() - startFloat);
|
||||
}
|
||||
}
|
||||
@@ -36,7 +36,7 @@ public class IntEvaluator implements TypeEvaluator {
|
||||
* <code>fraction</code> parameter.
|
||||
*/
|
||||
public Object evaluate(float fraction, Object startValue, Object endValue) {
|
||||
int startInt = (Integer) startValue;
|
||||
return (int) (startInt + fraction * ((Integer) endValue - startInt));
|
||||
int startInt = ((Number) startValue).intValue();
|
||||
return (int) (startInt + fraction * (((Number) endValue).intValue() - startInt));
|
||||
}
|
||||
}
|
||||
@@ -33,35 +33,13 @@ import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
* are then determined internally and the animation will call these functions as necessary to
|
||||
* animate the property.
|
||||
*/
|
||||
public final class PropertyAnimator extends Animator {
|
||||
public final class PropertyAnimator<T> extends Animator<T> {
|
||||
|
||||
// The target object on which the property exists, set in the constructor
|
||||
private Object mTarget;
|
||||
|
||||
private String mPropertyName;
|
||||
|
||||
private Method mGetter = null;
|
||||
|
||||
// The property setter that is assigned internally, based on the propertyName passed into
|
||||
// the constructor
|
||||
private Method mSetter;
|
||||
|
||||
// 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<Object, HashMap<String, Method>> sSetterPropertyMap =
|
||||
new HashMap<Object, HashMap<String, Method>>();
|
||||
private static final HashMap<Object, HashMap<String, Method>> sGetterPropertyMap =
|
||||
new HashMap<Object, HashMap<String, Method>>();
|
||||
|
||||
// This lock is used to ensure that only one thread is accessing the property maps
|
||||
// at a time.
|
||||
private ReentrantReadWriteLock propertyMapLock = new ReentrantReadWriteLock();
|
||||
|
||||
// Used to pass single value to varargs parameter in setter invocation
|
||||
private Object[] mTmpValueArray = new Object[1];
|
||||
|
||||
|
||||
/**
|
||||
* 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.
|
||||
@@ -75,9 +53,19 @@ public final class PropertyAnimator extends Animator {
|
||||
* <code>valueFrom</code> and <code>valueTo</code> properties, otherwise the call to
|
||||
* the setter function will fail.</p>
|
||||
*
|
||||
* <p>If this PropertyAnimator has been set up to animate several properties together,
|
||||
* using more than one PropertyValuesHolder objects, then setting the propertyName simply
|
||||
* sets the propertyName in the first of those PropertyValuesHolder objects.</p>
|
||||
*
|
||||
* @param propertyName The name of the property being animated.
|
||||
*/
|
||||
public void setPropertyName(String propertyName) {
|
||||
if (mValues != null) {
|
||||
// should always be the case
|
||||
PropertyValuesHolder valuesHolder = mValues.get(mFirstPropertyName);
|
||||
valuesHolder.setPropertyName(propertyName);
|
||||
mFirstPropertyName = propertyName;
|
||||
}
|
||||
mPropertyName = propertyName;
|
||||
}
|
||||
|
||||
@@ -93,67 +81,6 @@ public final class PropertyAnimator extends Animator {
|
||||
return mPropertyName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the <code>Method</code> that is called with the animated values calculated
|
||||
* during the animation. Setting the setter method is an alternative to supplying a
|
||||
* {@link #setPropertyName(String) propertyName} from which the method is derived. This
|
||||
* approach is more direct, and is especially useful when a function must be called that does
|
||||
* not correspond to the convention of <code>setName()</code>. For example, if a function
|
||||
* called <code>offset()</code> is to be called with the animated values, there is no way
|
||||
* to tell <code>PropertyAnimator</code> how to call that function simply through a property
|
||||
* name, so a setter method should be supplied instead.
|
||||
*
|
||||
* <p>Note that the setter function 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 setter The setter method that should be called with the animated values.
|
||||
*/
|
||||
public void setSetter(Method setter) {
|
||||
mSetter = setter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the <code>Method</code> that is called with the animated values calculated
|
||||
* during the animation.
|
||||
*/
|
||||
public Method getSetter() {
|
||||
return mSetter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the <code>Method</code> that is called to get unsupplied <code>valueFrom</code> or
|
||||
* <code>valueTo</code> properties. Setting the getter method is an alternative to supplying a
|
||||
* {@link #setPropertyName(String) propertyName} from which the method is derived. This
|
||||
* approach is more direct, and is especially useful when a function must be called that does
|
||||
* not correspond to the convention of <code>setName()</code>. For example, if a function
|
||||
* called <code>offset()</code> is to be called to get an initial value, there is no way
|
||||
* to tell <code>PropertyAnimator</code> how to call that function simply through a property
|
||||
* name, so a getter method should be supplied instead.
|
||||
*
|
||||
* <p>Note that the getter method is only called whether supplied here or derived
|
||||
* from the property name, if one of <code>valueFrom</code> or <code>valueTo</code> are
|
||||
* null. If both of those values are non-null, then there is no need to get one of the
|
||||
* values and the getter is not called.
|
||||
*
|
||||
* <p>Note that the getter function must return the same parameter type as the
|
||||
* <code>valueFrom</code> and <code>valueTo</code> properties (whichever of them are
|
||||
* non-null), otherwise the call to the getter function will fail.</p>
|
||||
*
|
||||
* @param getter The getter method that should be called to get initial animation values.
|
||||
*/
|
||||
public void setGetter(Method getter) {
|
||||
mGetter = getter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the <code>Method</code> that is called to get unsupplied <code>valueFrom</code> or
|
||||
* <code>valueTo</code> properties.
|
||||
*/
|
||||
public Method getGetter() {
|
||||
return mGetter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new animation whose parameters come from the specified context and
|
||||
* attributes set.
|
||||
@@ -167,7 +94,8 @@ public final class PropertyAnimator extends Animator {
|
||||
TypedArray a = context.obtainStyledAttributes(attrs,
|
||||
com.android.internal.R.styleable.PropertyAnimator);
|
||||
|
||||
mPropertyName = a.getString(com.android.internal.R.styleable.PropertyAnimator_propertyName);
|
||||
setPropertyName(a.getString(
|
||||
com.android.internal.R.styleable.PropertyAnimator_propertyName));
|
||||
|
||||
|
||||
a.recycle();
|
||||
@@ -203,224 +131,42 @@ public final class PropertyAnimator extends Animator {
|
||||
}
|
||||
|
||||
/**
|
||||
* A constructor that takes <code>float</code> values. When this constructor
|
||||
* is called, the system expects to find a setter for <code>propertyName</code> on
|
||||
* the target object that takes a <code>float</code> value.
|
||||
* A constructor that takes a single property name and set of values. This constructor is
|
||||
* used in the simple case of animating a single property.
|
||||
*
|
||||
* @param duration The length of the animation, in milliseconds.
|
||||
* @param target The object whose property is to be animated. This object should
|
||||
* have a public function on it called <code>setName()</code>, where <code>name</code> is
|
||||
* the name of the property passed in as the <code>propertyName</code> parameter.
|
||||
* @param propertyName The name of the property on the <code>target</code> object
|
||||
* that will be animated. Given this name, the constructor will search for a
|
||||
* setter on the target object with the name <code>setPropertyName</code>. For example,
|
||||
* if the constructor is called with <code>propertyName = "foo"</code>, then the
|
||||
* target object should have a setter function with the name <code>setFoo()</code>.
|
||||
* @param valueFrom The initial value of the property when the animation begins.
|
||||
* @param valueTo The value to which the property will animate.
|
||||
* have a public method on it called <code>setName()</code>, where <code>name</code> is
|
||||
* the value of the <code>propertyName</code> parameter.
|
||||
* @param propertyName The name of the property being animated.
|
||||
* @param values The set of values to animate between. If there is only one value, it
|
||||
* is assumed to be the final value being animated to, and the initial value will be
|
||||
* derived on the fly.
|
||||
*/
|
||||
public PropertyAnimator(int duration, Object target, String propertyName,
|
||||
float valueFrom, float valueTo) {
|
||||
super(duration, valueFrom, valueTo);
|
||||
public PropertyAnimator(long duration, Object target, String propertyName, T...values) {
|
||||
super(duration, (T[]) values);
|
||||
mTarget = target;
|
||||
mPropertyName = propertyName;
|
||||
setPropertyName(propertyName);
|
||||
}
|
||||
|
||||
/**
|
||||
* A constructor that takes a single <code>float</code> value, which is the value that the
|
||||
* target object will animate to. When this constructor
|
||||
* is called, the system expects to find a setter for <code>propertyName</code> on
|
||||
* the target object that takes a value of the same type as the <code>Object</code>s. The
|
||||
* system also expects to find a similar getter function with which to derive the starting
|
||||
* value for the animation.
|
||||
* A constructor that takes <code>PropertyValueHolder</code> values. This constructor should
|
||||
* be used when animating several properties at once with the same PropertyAnimator, since
|
||||
* PropertyValuesHolder allows you to associate a set of animation values with a property
|
||||
* name.
|
||||
*
|
||||
* @param duration The length of the animation, in milliseconds.
|
||||
* @param target The object whose property is to be animated. This object should
|
||||
* have a public function on it called <code>setName()</code>, where <code>name</code> is
|
||||
* the name of the property passed in as the <code>propertyName</code> parameter.
|
||||
* @param propertyName The name of the property on the <code>target</code> object
|
||||
* that will be animated. Given this name, the constructor will search for a
|
||||
* setter on the target object with the name <code>setPropertyName</code>. For example,
|
||||
* if the constructor is called with <code>propertyName = "foo"</code>, then the
|
||||
* target object should have a setter function with the name <code>setFoo()</code>.
|
||||
* @param valueTo The value to which the property will animate.
|
||||
* have public methods on it called <code>setName()</code>, where <code>name</code> is
|
||||
* the name of the property passed in as the <code>propertyName</code> parameter for
|
||||
* each of the PropertyValuesHolder objects.
|
||||
* @param values The PropertyValuesHolder objects which hold each the property name and values
|
||||
* to animate that property between.
|
||||
*/
|
||||
public PropertyAnimator(int duration, Object target, String propertyName, float valueTo) {
|
||||
super(duration, valueTo);
|
||||
public PropertyAnimator(long duration, Object target, PropertyValuesHolder...values) {
|
||||
super(duration);
|
||||
setValues(values);
|
||||
mTarget = target;
|
||||
mPropertyName = propertyName;
|
||||
}
|
||||
|
||||
/**
|
||||
* A constructor that takes <code>int</code> values. When this constructor
|
||||
* is called, the system expects to find a setter for <code>propertyName</code> on
|
||||
* the target object that takes a <code>int</code> value.
|
||||
*
|
||||
* @param duration The length of the animation, in milliseconds.
|
||||
* @param target The object whose property is to be animated. This object should
|
||||
* have a public function on it called <code>setName()</code>, where <code>name</code> is
|
||||
* the name of the property passed in as the <code>propertyName</code> parameter.
|
||||
* @param propertyName The name of the property on the <code>target</code> object
|
||||
* that will be animated. Given this name, the constructor will search for a
|
||||
* setter on the target object with the name <code>setPropertyName</code>. For example,
|
||||
* if the constructor is called with <code>propertyName = "foo"</code>, then the
|
||||
* target object should have a setter function with the name <code>setFoo()</code>.
|
||||
* @param valueFrom The initial value of the property when the animation begins.
|
||||
* @param valueTo The value to which the property will animate.
|
||||
*/
|
||||
public PropertyAnimator(int duration, Object target, String propertyName,
|
||||
int valueFrom, int valueTo) {
|
||||
super(duration, valueFrom, valueTo);
|
||||
mTarget = target;
|
||||
mPropertyName = propertyName;
|
||||
}
|
||||
|
||||
/**
|
||||
* A constructor that takes a single <code>int</code> value, which is the value that the
|
||||
* target object will animate to. When this constructor
|
||||
* is called, the system expects to find a setter for <code>propertyName</code> on
|
||||
* the target object that takes a value of the same type as the <code>Object</code>s. The
|
||||
* system also expects to find a similar getter function with which to derive the starting
|
||||
* value for the animation.
|
||||
*
|
||||
* @param duration The length of the animation, in milliseconds.
|
||||
* @param target The object whose property is to be animated. This object should
|
||||
* have a public function on it called <code>setName()</code>, where <code>name</code> is
|
||||
* the name of the property passed in as the <code>propertyName</code> parameter.
|
||||
* @param propertyName The name of the property on the <code>target</code> object
|
||||
* that will be animated. Given this name, the constructor will search for a
|
||||
* setter on the target object with the name <code>setPropertyName</code>. For example,
|
||||
* if the constructor is called with <code>propertyName = "foo"</code>, then the
|
||||
* target object should have a setter function with the name <code>setFoo()</code>.
|
||||
* @param valueTo The value to which the property will animate.
|
||||
*/
|
||||
public PropertyAnimator(int duration, Object target, String propertyName, int valueTo) {
|
||||
super(duration, valueTo);
|
||||
mTarget = target;
|
||||
mPropertyName = propertyName;
|
||||
}
|
||||
|
||||
/**
|
||||
* A constructor that takes <code>double</code> values. When this constructor
|
||||
* is called, the system expects to find a setter for <code>propertyName</code> on
|
||||
* the target object that takes a <code>double</code> value.
|
||||
*
|
||||
* @param duration The length of the animation, in milliseconds.
|
||||
* @param target The object whose property is to be animated. This object should
|
||||
* have a public function on it called <code>setName()</code>, where <code>name</code> is
|
||||
* the name of the property passed in as the <code>propertyName</code> parameter.
|
||||
* @param propertyName The name of the property on the <code>target</code> object
|
||||
* that will be animated. Given this name, the constructor will search for a
|
||||
* setter on the target object with the name <code>setPropertyName</code>. For example,
|
||||
* if the constructor is called with <code>propertyName = "foo"</code>, then the
|
||||
* target object should have a setter function with the name <code>setFoo()</code>.
|
||||
* @param valueFrom The initial value of the property when the animation begins.
|
||||
* @param valueTo The value to which the property will animate.
|
||||
*/
|
||||
public PropertyAnimator(int duration, Object target, String propertyName,
|
||||
double valueFrom, double valueTo) {
|
||||
super(duration, valueFrom, valueTo);
|
||||
mTarget = target;
|
||||
mPropertyName = propertyName;
|
||||
}
|
||||
|
||||
/**
|
||||
* A constructor that takes a single <code>double</code> value, which is the value that the
|
||||
* target object will animate to. When this constructor
|
||||
* is called, the system expects to find a setter for <code>propertyName</code> on
|
||||
* the target object that takes a value of the same type as the <code>Object</code>s. The
|
||||
* system also expects to find a similar getter function with which to derive the starting
|
||||
* value for the animation.
|
||||
*
|
||||
* @param duration The length of the animation, in milliseconds.
|
||||
* @param target The object whose property is to be animated. This object should
|
||||
* have a public function on it called <code>setName()</code>, where <code>name</code> is
|
||||
* the name of the property passed in as the <code>propertyName</code> parameter.
|
||||
* @param propertyName The name of the property on the <code>target</code> object
|
||||
* that will be animated. Given this name, the constructor will search for a
|
||||
* setter on the target object with the name <code>setPropertyName</code>. For example,
|
||||
* if the constructor is called with <code>propertyName = "foo"</code>, then the
|
||||
* target object should have a setter function with the name <code>setFoo()</code>.
|
||||
* @param valueTo The value to which the property will animate.
|
||||
*/
|
||||
public PropertyAnimator(int duration, Object target, String propertyName, double valueTo) {
|
||||
super(duration, valueTo);
|
||||
mTarget = target;
|
||||
mPropertyName = propertyName;
|
||||
}
|
||||
|
||||
/**
|
||||
* A constructor that takes <code>Object</code> values. When this constructor
|
||||
* is called, the system expects to find a setter for <code>propertyName</code> on
|
||||
* the target object that takes a value of the same type as the <code>Object</code>s.
|
||||
*
|
||||
* @param duration The length of the animation, in milliseconds.
|
||||
* @param target The object whose property is to be animated. This object should
|
||||
* have a public function on it called <code>setName()</code>, where <code>name</code> is
|
||||
* the name of the property passed in as the <code>propertyName</code> parameter.
|
||||
* @param propertyName The name of the property on the <code>target</code> object
|
||||
* that will be animated. Given this name, the constructor will search for a
|
||||
* setter on the target object with the name <code>setPropertyName</code>. For example,
|
||||
* if the constructor is called with <code>propertyName = "foo"</code>, then the
|
||||
* target object should have a setter function with the name <code>setFoo()</code>.
|
||||
* @param valueFrom The initial value of the property when the animation begins.
|
||||
* @param valueTo The value to which the property will animate.
|
||||
*/
|
||||
public PropertyAnimator(int duration, Object target, String propertyName,
|
||||
Object valueFrom, Object valueTo) {
|
||||
super(duration, valueFrom, valueTo);
|
||||
mTarget = target;
|
||||
mPropertyName = propertyName;
|
||||
}
|
||||
|
||||
/**
|
||||
* A constructor that takes a single <code>Object</code> value, which is the value that the
|
||||
* target object will animate to. When this constructor
|
||||
* is called, the system expects to find a setter for <code>propertyName</code> on
|
||||
* the target object that takes a value of the same type as the <code>Object</code>s. The
|
||||
* system also expects to find a similar getter function with which to derive the starting
|
||||
* value for the animation.
|
||||
*
|
||||
* @param duration The length of the animation, in milliseconds.
|
||||
* @param target The object whose property is to be animated. This object should
|
||||
* have a public function on it called <code>setName()</code>, where <code>name</code> is
|
||||
* the name of the property passed in as the <code>propertyName</code> parameter.
|
||||
* @param propertyName The name of the property on the <code>target</code> object
|
||||
* that will be animated. Given this name, the constructor will search for a
|
||||
* setter on the target object with the name <code>setPropertyName</code>. For example,
|
||||
* if the constructor is called with <code>propertyName = "foo"</code>, then the
|
||||
* target object should have a setter function with the name <code>setFoo()</code>.
|
||||
* @param valueTo The value to which the property will animate.
|
||||
*/
|
||||
public PropertyAnimator(int duration, Object target, String propertyName, Object valueTo) {
|
||||
this(duration, target, propertyName, null, valueTo);
|
||||
}
|
||||
|
||||
/**
|
||||
* A constructor that takes <code>Keyframe</code>s. When this constructor
|
||||
* is called, the system expects to find a setter for <code>propertyName</code> on
|
||||
* the target object that takes a value of the same type as that returned from
|
||||
* {@link Keyframe#getType()}.
|
||||
* .
|
||||
*
|
||||
* @param duration The length of the animation, in milliseconds.
|
||||
* @param target The object whose property is to be animated. This object should
|
||||
* have a public function on it called <code>setName()</code>, where <code>name</code> is
|
||||
* the name of the property passed in as the <code>propertyName</code> parameter.
|
||||
* @param propertyName The name of the property on the <code>target</code> object
|
||||
* that will be animated. Given this name, the constructor will search for a
|
||||
* setter on the target object with the name <code>setPropertyName</code>. For example,
|
||||
* if the constructor is called with <code>propertyName = "foo"</code>, then the
|
||||
* target object should have a setter function with the name <code>setFoo()</code>.
|
||||
* @param keyframes The set of keyframes that define the times and values for the animation.
|
||||
* These keyframes should be ordered in increasing time value, should have a starting
|
||||
* keyframe with a fraction of 0 and and ending keyframe with a fraction of 1.
|
||||
*/
|
||||
public PropertyAnimator(int duration, Object target, String propertyName,
|
||||
Keyframe...keyframes) {
|
||||
super(duration, keyframes);
|
||||
mTarget = target;
|
||||
mPropertyName = propertyName;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -438,64 +184,8 @@ public final class PropertyAnimator extends Animator {
|
||||
@Override
|
||||
void initAnimation() {
|
||||
super.initAnimation();
|
||||
if (mSetter == 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
|
||||
propertyMapLock.writeLock().lock();
|
||||
HashMap<String, Method> propertyMap = sSetterPropertyMap.get(mTarget);
|
||||
if (propertyMap != null) {
|
||||
mSetter = propertyMap.get(mPropertyName);
|
||||
}
|
||||
if (mSetter == null) {
|
||||
mSetter = getPropertyFunction("set", mValueType);
|
||||
if (propertyMap == null) {
|
||||
propertyMap = new HashMap<String, Method>();
|
||||
sSetterPropertyMap.put(mTarget, propertyMap);
|
||||
}
|
||||
propertyMap.put(mPropertyName, mSetter);
|
||||
}
|
||||
} finally {
|
||||
propertyMapLock.writeLock().unlock();
|
||||
}
|
||||
}
|
||||
if (getKeyframes() == null && (getValueFrom() == null || getValueTo() == null)) {
|
||||
// Need to set up the getter if not set by the user, then call it
|
||||
// to get the initial values
|
||||
if (mGetter == null) {
|
||||
try {
|
||||
propertyMapLock.writeLock().lock();
|
||||
HashMap<String, Method> propertyMap = sGetterPropertyMap.get(mTarget);
|
||||
if (propertyMap != null) {
|
||||
mGetter = propertyMap.get(mPropertyName);
|
||||
}
|
||||
if (mGetter == null) {
|
||||
mGetter = getPropertyFunction("get", null);
|
||||
if (propertyMap == null) {
|
||||
propertyMap = new HashMap<String, Method>();
|
||||
sGetterPropertyMap.put(mTarget, propertyMap);
|
||||
}
|
||||
propertyMap.put(mPropertyName, mGetter);
|
||||
}
|
||||
} finally {
|
||||
propertyMapLock.writeLock().unlock();
|
||||
}
|
||||
}
|
||||
try {
|
||||
if (getValueFrom() == null) {
|
||||
setValueFrom(mGetter.invoke(mTarget));
|
||||
}
|
||||
if (getValueTo() == null) {
|
||||
setValueTo(mGetter.invoke(mTarget));
|
||||
}
|
||||
} catch (IllegalArgumentException e) {
|
||||
Log.e("PropertyAnimator", e.toString());
|
||||
} catch (IllegalAccessException e) {
|
||||
Log.e("PropertyAnimator", e.toString());
|
||||
} catch (InvocationTargetException e) {
|
||||
Log.e("PropertyAnimator", e.toString());
|
||||
}
|
||||
for (PropertyValuesHolder valuesHolder : mValues.values()) {
|
||||
valuesHolder.setupSetterAndGetter(mTarget);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -533,23 +223,8 @@ public final class PropertyAnimator extends Animator {
|
||||
@Override
|
||||
void animateValue(float fraction) {
|
||||
super.animateValue(fraction);
|
||||
if (mSetter != null) {
|
||||
try {
|
||||
mTmpValueArray[0] = getAnimatedValue();
|
||||
mSetter.invoke(mTarget, mTmpValueArray);
|
||||
} catch (InvocationTargetException e) {
|
||||
Log.e("PropertyAnimator", e.toString());
|
||||
} catch (IllegalAccessException e) {
|
||||
Log.e("PropertyAnimator", e.toString());
|
||||
}
|
||||
for (PropertyValuesHolder valuesHolder : mValues.values()) {
|
||||
valuesHolder.setAnimatedValue(mTarget);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Animator: target: " + this.mTarget + "\n" +
|
||||
" property: " + mPropertyName + "\n" +
|
||||
" from: " + getValueFrom() + "\n" +
|
||||
" to: " + getValueTo();
|
||||
}
|
||||
}
|
||||
|
||||
514
core/java/android/animation/PropertyValuesHolder.java
Normal file
514
core/java/android/animation/PropertyValuesHolder.java
Normal file
@@ -0,0 +1,514 @@
|
||||
/*
|
||||
* 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 android.animation;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
|
||||
/**
|
||||
*/
|
||||
public class PropertyValuesHolder<T> {
|
||||
|
||||
/**
|
||||
* The name of the property associated with the values. This need not be a real property,
|
||||
* unless this object is being used with PropertyAnimator. But this is the name by which
|
||||
* aniamted values are looked up with getAnimatedValue(String) in Animator.
|
||||
*/
|
||||
private String mPropertyName;
|
||||
|
||||
/**
|
||||
* The setter function, if needed. PropertyAnimator hands off this functionality to
|
||||
* PropertyValuesHolder, since it holds all of the per-property information. This
|
||||
* property can be manually set via setSetter(). Otherwise, it is automatically
|
||||
* derived when the animation starts in setupSetterAndGetter() if using PropertyAnimator.
|
||||
*/
|
||||
private Method mSetter = null;
|
||||
|
||||
/**
|
||||
* The getter function, if needed. PropertyAnimator hands off this functionality to
|
||||
* PropertyValuesHolder, since it holds all of the per-property information. This
|
||||
* property can be manually set via setSetter(). Otherwise, it is automatically
|
||||
* derived when the animation starts in setupSetterAndGetter() if using PropertyAnimator.
|
||||
* 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.
|
||||
*/
|
||||
private Class mValueType;
|
||||
|
||||
/**
|
||||
* The set of keyframes (time/value pairs) that define this animation.
|
||||
*/
|
||||
private KeyframeSet mKeyframeSet = null;
|
||||
|
||||
|
||||
// type evaluators for the three primitive types handled by this implementation
|
||||
private static final TypeEvaluator sIntEvaluator = new IntEvaluator();
|
||||
private static final TypeEvaluator sFloatEvaluator = new FloatEvaluator();
|
||||
private static final TypeEvaluator sDoubleEvaluator = new DoubleEvaluator();
|
||||
|
||||
// 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.
|
||||
private ReentrantReadWriteLock propertyMapLock = new ReentrantReadWriteLock();
|
||||
|
||||
// Used to pass single value to varargs parameter in setter invocation
|
||||
private 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, double, 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 Animator.animatedValue() or
|
||||
* by the property-setting logic in PropertyAnimator.animatedValue().
|
||||
*/
|
||||
private Object mAnimatedValue;
|
||||
|
||||
/**
|
||||
* Constructs a PropertyValuesHolder object with just a set of values. This constructor
|
||||
* is typically not used when animating objects with PropertyAnimator, because that
|
||||
* object needs distinct and meaningful property names. Simpler animations of one
|
||||
* set of values using Animator may use this constructor, however, because no
|
||||
* distinguishing name is needed.
|
||||
* @param values The set of values to animate between. If there is only one value, it
|
||||
* is assumed to be the final value being animated to, and the initial value will be
|
||||
* derived on the fly.
|
||||
*/
|
||||
public PropertyValuesHolder(T...values) {
|
||||
this(null, values);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs 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 android.animation.PropertyAnimator}, and with a getter function either
|
||||
* derived automatically from <code>propertyName</code> or set explicitly via
|
||||
* {@link #setGetter(java.lang.reflect.Method)}, 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 PropertyAnimator object, or
|
||||
* just a name used to get animated values, such as if this object is used with an
|
||||
* Animator object.
|
||||
* @param values The set of values to animate between.
|
||||
*/
|
||||
public PropertyValuesHolder(String propertyName, T... values) {
|
||||
mPropertyName = propertyName;
|
||||
setValues(values);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the values being animated between.
|
||||
* 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 android.animation.PropertyAnimator}, and with a getter function either
|
||||
* derived automatically from <code>propertyName</code> or set explicitly via
|
||||
* {@link #setGetter(java.lang.reflect.Method)}, since otherwise PropertyValuesHolder has
|
||||
* no way of determining what the value should be.
|
||||
* @param values The set of values to animate between.
|
||||
*/
|
||||
public void setValues(T... values) {
|
||||
int numKeyframes = values.length;
|
||||
for (int i = 0; i < numKeyframes; ++i) {
|
||||
if (values[i] != null) {
|
||||
Class thisValueType = values[i].getClass();
|
||||
if (mValueType == null) {
|
||||
mValueType = thisValueType;
|
||||
} else {
|
||||
if (thisValueType != mValueType) {
|
||||
if (mValueType == Integer.class &&
|
||||
(thisValueType == Float.class || thisValueType == Double.class)) {
|
||||
mValueType = thisValueType;
|
||||
} else if (mValueType == Float.class && thisValueType == Double.class) {
|
||||
mValueType = thisValueType;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Keyframe keyframes[] = new Keyframe[Math.max(numKeyframes,2)];
|
||||
if (mValueType.equals(Keyframe.class)) {
|
||||
mValueType = ((Keyframe)values[0]).getType();
|
||||
for (int i = 0; i < numKeyframes; ++i) {
|
||||
keyframes[i] = (Keyframe)values[i];
|
||||
}
|
||||
} else {
|
||||
if (numKeyframes == 1) {
|
||||
keyframes[0] = new Keyframe(0f, null);
|
||||
keyframes[1] = new Keyframe(1f, values[0]);
|
||||
} else {
|
||||
keyframes[0] = new Keyframe(0f, values[0]);
|
||||
for (int i = 1; i < numKeyframes; ++i) {
|
||||
if (values[i] != null && (values[i].getClass() != mValueType)) {
|
||||
|
||||
}
|
||||
keyframes[i] = new Keyframe((float) i / (numKeyframes - 1), values[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
mKeyframeSet = new KeyframeSet(keyframes);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 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 firstLetter = mPropertyName.substring(0, 1);
|
||||
String theRest = mPropertyName.substring(1);
|
||||
firstLetter = firstLetter.toUpperCase();
|
||||
String methodName = prefix + firstLetter + theRest;
|
||||
Class args[] = null;
|
||||
if (valueType == null) {
|
||||
try {
|
||||
returnVal = targetClass.getMethod(methodName, args);
|
||||
} catch (NoSuchMethodException e) {
|
||||
Log.e("PropertyValuesHolder",
|
||||
"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);
|
||||
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 setter/getter for property " + mPropertyName +
|
||||
"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
|
||||
// TODO: can we store the setter/getter per Class instead of per Object?
|
||||
propertyMapLock.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 {
|
||||
propertyMapLock.writeLock().unlock();
|
||||
}
|
||||
return setterOrGetter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility function to get the setter from targetClass
|
||||
* @param targetClass The Class on which the requested method should exist.
|
||||
*/
|
||||
private 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 PropertyAnimator) 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) {
|
||||
Class targetClass = target.getClass();
|
||||
if (mSetter == null) {
|
||||
setupSetter(targetClass);
|
||||
}
|
||||
for (Keyframe kf : mKeyframeSet.mKeyframes) {
|
||||
if (kf.getValue() == null) {
|
||||
if (mGetter == null) {
|
||||
setupGetter(targetClass);
|
||||
}
|
||||
try {
|
||||
kf.setValue((T) mGetter.invoke(target));
|
||||
} catch (InvocationTargetException e) {
|
||||
Log.e("PropertyValuesHolder", e.toString());
|
||||
} catch (IllegalAccessException e) {
|
||||
Log.e("PropertyValuesHolder", e.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 PropertyAnimator
|
||||
* to handle turning the value calculated by Animator 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 (mSetter != null) {
|
||||
try {
|
||||
mTmpValueArray[0] = mAnimatedValue;
|
||||
mSetter.invoke(target, mTmpValueArray);
|
||||
} catch (InvocationTargetException e) {
|
||||
Log.e("PropertyValuesHolder", e.toString());
|
||||
} catch (IllegalAccessException e) {
|
||||
Log.e("PropertyValuesHolder", e.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal function, called by Animator, to set up the TypeEvaluator that will be used
|
||||
* to calculate animated values.
|
||||
*/
|
||||
void init() {
|
||||
if (mEvaluator == null) {
|
||||
mEvaluator = (mValueType == int.class) ? sIntEvaluator :
|
||||
(mValueType == double.class) ? sDoubleEvaluator : sFloatEvaluator;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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, double, and int (and their Object equivalents, Float, Double,
|
||||
* and Integer) are correctly interpolated; all other types require setting a TypeEvaluator.
|
||||
* @param evaluator
|
||||
*/
|
||||
public void setEvaluator(TypeEvaluator evaluator) {
|
||||
mEvaluator = evaluator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function used to calculate the value according to the evaluator set up for
|
||||
* this PropertyValuesHolder object. This function is called by Animator.animateValue().
|
||||
*
|
||||
* @param fraction The elapsed, interpolated fraction of the animation.
|
||||
* @return The calculated value at this point in the animation.
|
||||
*/
|
||||
Object calculateValue(float fraction) {
|
||||
mAnimatedValue = mKeyframeSet.getValue(fraction, mEvaluator);
|
||||
return mAnimatedValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the <code>Method</code> that is called with the animated values calculated
|
||||
* during the animation. Setting the setter method is an alternative to supplying a
|
||||
* {@link #setPropertyName(String) propertyName} from which the method is derived. This
|
||||
* approach is more direct, and is especially useful when a function must be called that does
|
||||
* not correspond to the convention of <code>setName()</code>. For example, if a function
|
||||
* called <code>offset()</code> is to be called with the animated values, there is no way
|
||||
* to tell <code>PropertyAnimator</code> how to call that function simply through a property
|
||||
* name, so a setter method should be supplied instead.
|
||||
*
|
||||
* <p>Note that the setter function 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 setter The setter method that should be called with the animated values.
|
||||
*/
|
||||
public void setSetter(Method setter) {
|
||||
mSetter = setter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the <code>Method</code> that is called with the animated values calculated
|
||||
* during the animation.
|
||||
*/
|
||||
public Method getSetter() {
|
||||
return mSetter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the <code>Method</code> that is called to get unsupplied <code>valueFrom</code> or
|
||||
* <code>valueTo</code> properties. Setting the getter method is an alternative to supplying a
|
||||
* {@link #setPropertyName(String) propertyName} from which the method is derived. This
|
||||
* approach is more direct, and is especially useful when a function must be called that does
|
||||
* not correspond to the convention of <code>setName()</code>. For example, if a function
|
||||
* called <code>offset()</code> is to be called to get an initial value, there is no way
|
||||
* to tell <code>PropertyAnimator</code> how to call that function simply through a property
|
||||
* name, so a getter method should be supplied instead.
|
||||
*
|
||||
* <p>Note that the getter method is only called whether supplied here or derived
|
||||
* from the property name, if one of <code>valueFrom</code> or <code>valueTo</code> are
|
||||
* null. If both of those values are non-null, then there is no need to get one of the
|
||||
* values and the getter is not called.
|
||||
*
|
||||
* <p>Note that the getter function must return the same parameter type as the
|
||||
* <code>valueFrom</code> and <code>valueTo</code> properties (whichever of them are
|
||||
* non-null), otherwise the call to the getter function will fail.</p>
|
||||
*
|
||||
* @param getter The getter method that should be called to get initial animation values.
|
||||
*/
|
||||
public void setGetter(Method getter) {
|
||||
mGetter = getter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the <code>Method</code> that is called to get unsupplied <code>valueFrom</code> or
|
||||
* <code>valueTo</code> properties.
|
||||
*/
|
||||
public Method getGetter() {
|
||||
return mGetter;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 Animator and PropertyAnimator, to retrieve the value
|
||||
* most recently calculated in calculateValue().
|
||||
* @return
|
||||
*/
|
||||
Object getAnimatedValue() {
|
||||
return mAnimatedValue;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user