属性动画之 Interpolators、Evaluator

Interpolators - 插值器

我们知道,属性动画的本质是在一个时间段内,动态的改变对象的属性,从而实现动画效果,打个比方,在 10 秒之内让数字从 1 过渡到 10,这个中间的过度值是由系统计算生成,最基本的也就是每秒 +1,Android 也提供了其他的过渡方式,由 Interpolators 来完成。

确切的说,Interpolators 是一个接口,其一系列的实现类实现了各种效果的计算过程:

  • AccelerateDecelerateInterpolator:变化频率在开始和结尾处慢,而在中间部分加速
  • AccelerateInterpolator:变化频率在开始慢,然后加速
  • AnticipateInterpolator:先向后,然后向前抛出(抛物运动)
  • AnticipateOvershootInterpolator:先向后,向前抛出并超过目标值,然后最终返回到目标值。
  • BounceInterpolator:在结束时反弹
  • CycleInterpolator:用指定的循环数,重复播放动画
  • DecelerateInterpolator:变化频率是快出,然后减速
  • LinearInterpolator:固定的变化频率
  • OvershootInterpolator:向前抛出,并超过目标值,然后再返回

如果上述实现类满足不了你的需求,你还可以自定义自己的插值器,需要实现以下接口:

  • TimeInterpolator:实现自定义插值的一个接口

我们通过调用动画对象的 setInterpolators 方法为动画设置插值器。

        ValueAnimator animator = ValueAnimator.ofInt(1, 10);
        animator.setDuration(500);
        animator.setInterpolator(new AccelerateDecelerateInterpolator());
        animator.start();

Evaluator

我们为Animator 设置了开始值和结束值,Interpolators 又为我们提供了数值过渡的速率,那么我就可以获取到某个事件内的值是多少,Evaluator 就可以帮助我们实现这个需求。

系统提供的 Evaluator:

  • IntEvaluator:默认的用于评价int类型属性计算值的评价器

  • FlaoatEvaluator:默认的用于评价float类型属性计算值的评价器

  • ArgbEvaluator:默认的用于评价颜色属性计算值的评价器,颜色属性值用十六进制表示

系统会根据我们的可变长参数自动判断是使用 IntEvaluator 还是 FlaoatEvaluator,至于 ArgbEvaluator,则是当参数为颜色值时使用。

如果这三个 Evaluator 无法满足我们的需求,还可以自定义 Evaluator,需实现 TypeEvaluator 接口:

  • TypeEvaluator:允许创建自定义评价器的接口。如果要让一个非int、float、颜色类型的属性具有动画效果,就必须实现这个TypeEvaluator接口,用它来指定如何计算对象属性动画值。如果想要处理有别于int、float和颜色类型默认行为的动画,也能够给它们指定一个自定义的TypeEvaluator。

如果想要的动画类型是 Android 系统所未知的,那么通过实现 TypeEvaluator 接口就能够创建自己的评价器。Android 系统已知的类型是 int、float 或颜色(color),分别有 IntEvaluator、FloatEvaluator 和 ArgbEvaluator 类型的评价器所支持。

在 TypeEvaluator 接口中只有一个要实现的方法:evaluate() 方法。这个方法允许正在使用的动画处理器返回一个适用于于当前动画时点动画属性值,FloatEvaluator 类演示了这个方法是如何做这件事的:

public class FloatEvaluator implements TypeEvaluator {
    public Object evaluate(float fraction, Object startValue, Object endValue) {
       float startFloat = ((Number) startValue).floatValue();
       return startFloat + fraction * (((Number) endValue).floatValue() - startFloat);
   }
}

注意:当 ValueAnimator 对象(或 ObjectAnimator 对象)运行时,它会计算当前的动画播放比例(一个 0 到 1 之间的值),然后根据你所使用的插值类型来计算一个要插入的动画的版本。插值比例是由 TypeEvaluator 对象通过 fraction 参数接收来的,因此在计算动画值的时候,不需要考虑插值。

自定义 Evaluator 用的比较少,这里是一个关于颜色变化的例子:

public class MainActivity extends AppCompatActivity {

    private LinearLayout ly_root;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        ly_root = (LinearLayout) findViewById(R.id.ly_root);

        ObjectAnimator anim = ObjectAnimator.ofObject(ly_root, "backgroundColor", new ArgbEvaluator(), Color.parseColor("#FFDAB9"), Color.parseColor("#FF6A6A"));
        anim.setRepeatCount(-1);
        anim.setDuration(5000);
        anim.setRepeatMode(ObjectAnimator.REVERSE);
        anim.start();

        Log.d("TTT", "start on:" + Color.parseColor("#FFDAB9") + "    end on:" + Color.parseColor("#FF6A6A"));


        anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                Log.d("TTT", "color = " + animation.getAnimatedValue());
            }
        });

    }
}
Copyright© 2020-2022 li-xyz 冀ICP备2022001112号-1