nterpolator这个东西很难进行翻译,直译过来的话是补间器的意思,它的主要作用是可以控制动画的变化速率,比如去实现一种非线性运动的动画效果。那么什么叫做非线性运动的动画效果呢?就是说动画改变的速率不是一成不变的,像加速运动以及减速运动都属于非线性运动。

不过Interpolator并不是属性动画中新增的技术,实际上从Android 1.0版本开始就一直存在Interpolator接口了,而之前的补间动画当然也是支持这个功能的。只不过在属性动画中新增了一个TimeInterpolator接口,这个接口是用于兼容之前的Interpolator的,这使得所有过去的Interpolator实现类都可以直接拿过来放到属性动画当中使用,那么我们来看一下现在TimeInterpolator接口的所有实现类,如下图所示:

可以看到,TimeInterpolator接口已经有非常多的实现类了,这些都是Android系统内置好的并且我们可以直接使用的Interpolator。每个Interpolator都有它各自的实现效果,比如说AccelerateInterpolator就是一个加速运动的Interpolator,而DecelerateInterpolator就是一个减速运动的Interpolator。

我觉得细心的朋友应该早已经发现了,在前面两篇文章当中我们所学到的所有属性动画,其实都不是在进行一种线程运动。比如说在“上”篇文章中使用ValueAnimator所打印的值如下所示:

可以看到,一开始的值变化速度明显比较慢,仅0.0开头的就打印了4次,之后开始加速,最后阶段又开始减速,因此我们可以很明显地看出这一个先加速后减速的Interpolator。

编写自定义Interpolator最主要的难度都是在于数学计算方面的,由于我数学并不是很好,因此这里也就写一个简单点的Interpolator来给大家演示一下。既然属性动画默认的Interpolator是先加速后减速的一种方式,这里我们就对它进行一个简单的修改,让它变成先减速后加速的方式。新建DecelerateAccelerateInterpolator类,让它实现TimeInterpolator接口,代码如下所示:

  1. public class DecelerateAccelerateInterpolator implements TimeInterpolator{
  2. @Override
  3. public float getInterpolation(float input) {
  4. float result;
  5. if (input <= 0.5) {
  6. result = (float) (Math.sin(Math.PI * input)) / 2;
  7. } else {
  8. result = (float) (2 - Math.sin(Math.PI * input)) / 2;
  9. }
  10. return result;
  11. }
  12. }

, RADIUS);

  • Point endPoint = new Point(getWidth() / 2, getHeight() - RADIUS);
  • ValueAnimator anim = ValueAnimator.ofObject(new PointEvaluator(), startPoint, endPoint);
  • anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
  • @Override
  • public void onAnimationUpdate(ValueAnimator animation) {
  • currentPoint = (Point) animation.getAnimatedValue();
  • invalidate();
  • }
  • });
  • anim.setInterpolator(new DecelerateAccelerateInterpolator());
  • anim.setDuration(3000);
  • anim.start();
  • }