Android动画中的 Evaluator

127 阅读2分钟

Android动画中的 Evaluator

Evaluator 介绍

Evaluator 全称是 TypeEvaluator,是提供给 ObjectAnimator 动画用于根据动画完成度来计算属性值的。

作用:
    * 对指定的某个类型的参数设定一个算法,来计算动画完成度和参数值的关系(动画完成度 -> 属性值)
    * 理解:例如动画完成10%的时候,参数值变成多少的算法。


ObjectAnimator.ofInt():
    * 默认:IntEvaluator();
    * 可以使用 setEvaluator() 方法设置为别的 TypeEvaluator,比如颜色使用 ArgbEvaluator;
    
ObjectAnimator.ofFloat():
    * 默认:FloatEvaluator();
    * 可以使用 setEvaluator() 方法设置为别的 TypeEvaluator;
对于没有自带支持的属性类型:
    * 用 ofObject(), 并把对应的自定义 TypeEvaluator 作为参数传入;

Evaluator 的用法

ObjectAnimator animator = ObjectAnimator.ofInt(this, "color", 0xffff0000, 0xff0000ff);
animator.setDuration(600);
animator.setEvaluator(new ArgbEvaluator());// 设置Evaluator
animator.start();

系统自带的 Evaluator

1.ArgbEvaluator
2.FloatEvaluator:是ofFloat构造的默认值
3.IntEvaluator:是ofInt构造的默认值
4.PointFEvaluator:关于点的坐标的 Evaluator 

自定义 Evaluator

案例1:让颜色平滑过度的Evaluator

/**
 * @Introduction: 颜色变化的 Evaluator
 * @Author: geaosu
 * @Email: geaosu@163.com
 * @Time: 2023年04月06日-星期四
 */
public class HsvEvaluator implements TypeEvaluator<Integer> {
    private float[] startHsv = new float[3];// 存放 RGB,所以数组长度是3
    private float[] endHsv = new float[3];
    private float[] outHsv = new float[3];

    private HsvEvaluator() {
    }

    public static HsvEvaluator getInstance() {
        return Holder.instance;
    }

    private static class Holder {
        private static final HsvEvaluator instance = new HsvEvaluator();
    }

    /**
     * 方法参数介绍
     * @param fraction   当前进度百分值,从起始值到结束值的分数
     * @param startValue 开始值
     * @param endValue   结束值
     * @return 当前进度对应的值
     */
    @Override
    public Integer evaluate(float fraction, Integer startValue, Integer endValue) {
        // 第1步:把 ARGB 转成 HSV
        Color.colorToHSV(startValue, startHsv);
        Color.colorToHSV(endValue, endHsv);

        // 第2步:计算当前动画完成度所对应的颜色值
        if (endHsv[0] - startHsv[0] > 180) {
            endHsv[0] -= 360;
        } else if (endHsv[0] - startHsv[0] < -180) {
            endHsv[0] += 360;
        }
        outHsv[0] = startHsv[0] + (endHsv[0] - startHsv[0]) * fraction;
        if (outHsv[0] > 360) {
            outHsv[0] -= 360;
        } else if (outHsv[0] < 0) {
            outHsv[0] += 360;
        }
        outHsv[1] = startHsv[1] + (endHsv[1] - startHsv[1]) * fraction;
        outHsv[2] = startHsv[2] + (endHsv[2] - startHsv[2]) * fraction;

        // 计算当前动画完成度所对应的透明度
        int alpha = startValue >> 24 + (int) ((endValue >> 24 - startValue >> 24) * fraction);

        // 第3步:把 HSV 转换回 ARGB
        return Color.HSVToColor(alpha, outHsv);
    }
}