TypeEvaluator 估值器
如果想要的动画类型是Android系统所未知的,那么通过实现TypeEvaluator接口就能够创建自己的估值器。
TypeEvaluator接口
public interface TypeEvaluator<T> {
/**
* @param fraction The fraction from the starting to the ending values
* @param startValue The start value.
* @param endValue The end value.
* @return A linear interpolation between the start and end values, given the
* <code>fraction</code> parameter.
*/
public T evaluate(float fraction, T startValue, T endValue);
}
Android系统已知的类型是int、float或颜色(color),分别有IntEvaluator、FloatEvaluator和ArgbEvaluator类型的评价器所支持。
在TypeEvaluator接口中只有一个要实现的方法:evaluate()方法。这个方法允许正在使用的动画处理器返回一个适用于于当前动画时点动画属性值。看下系统是怎么实现的
IntEvaluator.class
public class IntEvaluator implements TypeEvaluator<Integer> {
/**
* @param fraction The fraction from the starting to the ending values
* @param startValue The start value; should be of type <code>int</code> or
* <code>Integer</code>
* @param endValue The end value; should be of type <code>int</code> or <code>Integer</code>
* @return A linear interpolation between the start and end values, given the
* <code>fraction</code> parameter.
*/
public Integer evaluate(float fraction, Integer startValue, Integer endValue) {
int startInt = startValue;
return (int)(startInt + fraction * (endValue - startInt));
}
}
FloatEvaluator.class
public class FloatEvaluator implements TypeEvaluator<Number> {
/**
* @param fraction The fraction from the starting to the ending values
* @param startValue The start value; should be of type <code>float</code> or
* <code>Float</code>
* @param endValue The end value; should be of type <code>float</code> or <code>Float</code>
* @return A linear interpolation between the start and end values, given the
* <code>fraction</code> parameter.
*/
public Float evaluate(float fraction, Number startValue, Number endValue) {
float startFloat = startValue.floatValue();
return startFloat + fraction * (endValue.floatValue() - startFloat);
}
}
ArgbEvaluator.class
public class ArgbEvaluator implements TypeEvaluator {
private static final ArgbEvaluator sInstance = new ArgbEvaluator();
/**
* Returns an instance of <code>ArgbEvaluator</code> that may be used in
* {@link ValueAnimator#setEvaluator(TypeEvaluator)}. The same instance may
* be used in multiple <code>Animator</code>s because it holds no state.
* @return An instance of <code>ArgbEvalutor</code>.
*
* @hide
*/
public static ArgbEvaluator getInstance() {
return sInstance;
}
/**
* @param fraction The fraction from the starting to the ending values
* @param startValue A 32-bit int value representing colors in the
* separate bytes of the parameter
* @param endValue A 32-bit int value representing colors in the
* separate bytes of the parameter
* @return A value that is calculated to be the linearly interpolated
* result, derived by separating the start and end values into separate
* color channels and interpolating each one separately, recombining the
* resulting values in the same way.
*/
public Object evaluate(float fraction, Object startValue, Object endValue) {
int startInt = (Integer) startValue;
int startA = (startInt >> 24) & 0xff;
int startR = (startInt >> 16) & 0xff;
int startG = (startInt >> 8) & 0xff;
int startB = startInt & 0xff;
int endInt = (Integer) endValue;
int endA = (endInt >> 24) & 0xff;
int endR = (endInt >> 16) & 0xff;
int endG = (endInt >> 8) & 0xff;
int endB = endInt & 0xff;
return (int)((startA + (int)(fraction * (endA - startA))) << 24) |
(int)((startR + (int)(fraction * (endR - startR))) << 16) |
(int)((startG + (int)(fraction * (endG - startG))) << 8) |
(int)((startB + (int)(fraction * (endB - startB))));
}
}
看完以后,你会发现超级简单,就是实现了系统的接口,自己重写了抽象方法,通过要求的计算获取符合要求的值,只是类型不同而已。
再深入想想,:当ValueAnimator对 象(或ObjectAnimator对象)运行时,它会计算当前的动画播放比例(一个0到1之间的值),然后根据你所使用的插值类型来计算一个要插入的动 画的版本。插值比例是由TypeEvaluator对象通过fraction参数接收来的,因此在计算动画值的时候,不需要考虑插值。
好,下面我多举几个数据类型的,给大家多点重写的思路。
第一种,假如数据类型是 int[] 数组,怎么写,看代码
public class IntArrayEvaluator implements TypeEvaluator<int[]> {
private int[] mArray;
public IntArrayEvaluator() {
}
public IntArrayEvaluator(int[] reuseArray) {
mArray = reuseArray;
}
@Override
public int[] evaluate(float fraction, int[] startValue, int[] endValue) {
int[] array = mArray;
if (array == null) {
array = new int[startValue.length];
}
for (int i = 0; i < array.length; i++) {
int start = startValue[i];
int end = endValue[i];
array[i] = (int) (start + (fraction * (end - start)));
}
return array;
}
}
第二种,假如数据类型是 string[] 类型呢,看代码
public class FloatArrayEvaluator implements TypeEvaluator<float[]> {
private float[] mArray;
public FloatArrayEvaluator() {
}
public FloatArrayEvaluator(float[] reuseArray) {
mArray = reuseArray;
}
@Override
public float[] evaluate(float fraction, float[] startValue, float[] endValue) {
float[] array = mArray;
if (array == null) {
array = new float[startValue.length];
}
for (int i = 0; i < array.length; i++) {
float start = startValue[i];
float end = endValue[i];
array[i] = start + (fraction * (end - start));
}
return array;
}
}
我们也可以直接继承相应父类,重写里面的方法也可以,因为Object是最基类,我们可以实现任何的类型
第三种,假如数据类型是Object
class FloatEvaluator implements TypeEvaluator<Object> {
public Object evaluate(float fraction, Object startValue, Object endValue) {
float startFloat = ((Number) startValue).floatValue();
returnstartFloat + fraction * (((Number) endValue).floatValue() - startFloat);
}
}
第四种,假如数据类型是Drawable
class DrawableEvaluator implements TypeEvaluator<Drawable >{
public Drawable evaluate(float fraction, Drawable startValue, Drawable endValue) {
if (fraction < 0.5) {
return startValue;
} else {
return endValue;
}
}
};
第五种,假如数据类型是char
class CharEvaluator implements TypeEvaluator<Char>{
public Char evaluate(float fraction, CharstartValue, CharendValue) {
}
};
.....
数据类型,什么样的都可以,