属性动画-TypeEvaluator

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) {  
             
            }  
        }; 

.....

数据类型,什么样的都可以,





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值