Android属性动画进阶——插值器 Interpolator

Interpolator

Interpolator就是我们平时说的插值器。插值器什么意思呢?看到这三个字还真是不太好理解它到底干嘛用的。其实它就是控制动画的变化速率的。怎么控制?根据动画的时间完成度计算动画完成度。还是不懂?比如:我们一张图片沿Y正方向平移1200像素,时间是2000毫秒。如果是匀速平移,时间在1000秒的时候时间完成度是0.5,动画完成度也是0.5,那么位移应该是0.5*1200=600像素。这个时候图片应该平移到Y=600的地方。匀速的动画完成度随时间的变化如下图:

Interpolator是一个接口,继承了TimeInterpolator。只有一个未实现方法:getInterpolation(float input)。系统为我们提供了很多Interpolator的实现类,匀速只是其中一种,还有先加上再减速,一直加速等等很多。我们依次实现这些效果:

动画中依次实现了系统提供的种种Interpolator实现类,如下:

  • AccelerateDecelerateInterpolator 先加速再加速
  • LinearInterpolator 匀速
  • AccelerateInterpolator 持续加速
  • DecelerateInterpolator 持续减速
  • AnticipateInterpolator 先回拉一下
  • OvershootInterpolator 最后回弹一下
  • AnticipateOvershootInterpolator 先回拉再回弹
  • BounceInterpolator 结束时弹跳
  • CycleInterpolator 正余弦变化

其中先加速再减速是系统默认的变化速率。就是如果我们不设置这个值的时候,就是先加速再减速的效果。我们看看最简单的匀速LinearInterpolator累的实现,而且我们只需要关注getInterpolation(float input)方法的实现:

public class LinearInterpolator extends BaseInterpolator implements NativeInterpolatorFactory {

    public LinearInterpolator() {
    }

    public LinearInterpolator(Context context, AttributeSet attrs) {
    }

    public float getInterpolation(float input) {
        return input;
    }

    /** @hide */
    @Override
    public long createNativeInterpolator() {
        return NativeInterpolatorFactoryHelper.createLinearInterpolator();
    }

}

这个方法输出的就是我们的动画完成度,而输入的就是时间完成度。时间都是匀速走的,一秒一秒,我们无法让它加速或者减速。可以看出,匀速的实现很简单,直接返回输入参数。这是因为匀速的时候动画完成度和时间完成度是一样的。我们再看看默认的先加速再加速类:AccelerateDecelerateInterpolator

public class AccelerateDecelerateInterpolator extends BaseInterpolator
    implements NativeInterpolatorFactory {
    public AccelerateDecelerateInterpolator() {
    }

    @SuppressWarnings({"UnusedDeclaration"})
    public AccelerateDecelerateInterpolator(Context context,AttributeSet attrs) {
    }

    public float getInterpolation(float input) {
        return (float)(Math.cos((input + 1) * Math.PI) / 2.0f) + 0.5f;
    }

    /** @hide */
    @Override
    public long createNativeInterpolator() {
        return NativeInterpolatorFactoryHelper.createAccelerateDecelerateInterpolator();
    }

}

拿到时间完成度后,进行了一系列的运算,通过这个算法得到动画完成度。我们看一下它的曲线图:

从图片可以看出,动画的完成度的变化速率是先增大再变小。知道了插值器是什么以及怎么实现的之后,我们就可以实现自己的插值器了,让动画的变化速率按照我们的意愿来。我们先画出动画完成度随时间完成度的变化曲线:

Android属性动画进阶——插值器 Interpolator_第1张图片

简单手画了下,变化也很简单,数学好的可以做复杂的变化。。。然后我们定义一个类FirstInterpolator:

public class FirstInterpolator implements Interpolator {
    @Override
    public float getInterpolation(float input) {
        float f ;
        if (input < 0.25) {
            f = input *2;
        }else if (input < 0.5) {
            f = input*2 - 0.5f;
        }else if (input < 0.75){
            f = 0.5f;
        }else {
            f = input * 2 - 1;
        }

        return f;
    }
}

从曲线图可以看出,在时间完成度为0到0.25的时候,匀速变化,0.25到0.5的时候,回到出发点再匀速变化,0.5到0.75的时候是停止变化,0.75到1的时候接着匀速变化。效果如下:
Android属性动画进阶——插值器 Interpolator_第2张图片
可以看到,动画是按照我们设计的变化速率变化的。从这里就可以看出,Interpolator对于我们实现一些比较精致的效果是非常有帮助的,我们可以借助系统实现了的Interpolator类,也可以按照自己的意愿实现自己的Interpolator,它的作用不仅于此,也和我们后面要说的估值器有很紧密的关系。

你可能感兴趣的:(Android属性动画)