Android属性动画(三) TimeInterpolator(插值器)

OK,继续学习属性动画,本篇文章是属性动画系列的第三篇文章了,今天来学习一下属性动画中的TimeInterpolator,如果你对属性动画还不太熟悉,可以点击下面的链接学习一下前两篇文章的知识:

《Android属性动画(一) 初识基本用法》

《Android属性动画(二) ValueAnimator的实际应用 & 自定义TypeEvaluator》

1.介绍

先说说Interpolator,在Android 1.0版本中就已经有Interpolator接口了,可以翻译成插值器,用于计算补间动画的变化速率。Android团队在3.0版本中引入了属性动画,同时新增了TimeInterpolator接口,Interpolator继承于TimeInterpolator,这就使得Interpolator的实现类可以直接拿到属性动画中使用。

看下TimeInterpolator的实现类:

TimeInterpolator

可以看到,Android系统中已经内置了很多实现类了,比如AccelerateInterpolator就是加速运动的插值器,DecelerateInterpolator是减速运动的插值器,LinearInterpolator是匀速运动的差值器。
举个栗子,系统默认的插值器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();
    }
}

主要看下getInterpolation方法,接收一个float类型的input参数,input参数是由系统计算传入的,变化很有规律,就是根据动画的时长从0到1匀速增加,传入到下面的公式中,计算出当前属性值改变的百分比,这个值就是我们在上一篇文章中提到的fraction参数,TypeEvaluator(估值器)就是根据fraction参数来计算当前的属性值的。

AccelerateDecelerateInterpolator的变化曲线:

AccelerateDecelerateInterpolato

2.自定义TimeInterpolator

TimeInterpolator的实现类虽然很多,但不一定能满足我们的需求,这时候就需要我们来自定义一个TimeInterpolator来完成各种各样复杂的动画效果,接下来我们就自定义一个TimeInterpolator来实现一下图片的回弹效果,先看下实现后的效果:

回弹效果

首先定义一个JellyInterpolator类实现TimeInterpolator接口,重写getInterpolation方法:

public class JellyInterpolator implements TimeInterpolator {

    // 因子数值越小振动频率越高
    private float factor;

    public JellyInterpolator() {
        this.factor = 0.15f;
    }

    @Override
    public float getInterpolation(float input) {
        return (float) (Math.pow(2, -10 * input) * Math.sin((input - factor / 4) * (2 * Math.PI) / factor) + 1);
    }
}

看下JellyInterpolator的变化曲线:

JellyInterpolator

在Activity中设置属性动画:

public class InterpolatorActivity extends AppCompatActivity {

    @BindView(R.id.image)
    ImageView image;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_interpolator);
        ButterKnife.bind(this);
    }

    @OnClick(R.id.image)
    public void onClick() {
        ObjectAnimator scaleXAnimator = ObjectAnimator.ofFloat(image, "scaleX", 0f, 1f);
        ObjectAnimator scaleYAnimator = ObjectAnimator.ofFloat(image, "scaleY", 0f, 1f);
        AnimatorSet animatorSet = new AnimatorSet();
        animatorSet.playTogether(scaleXAnimator, scaleYAnimator);
        // 设置插值器
        animatorSet.setInterpolator(new JellyInterpolator());
        animatorSet.setDuration(3000);
        animatorSet.start();
    }
}

到这里一个自定义的TimeInterpolator就完成了,主要的难点就在公式计算了,分享一个可视化插值器的网站,其中内置了一些插值器公式,还可以查看动画演示效果。

Interpolator:http://inloop.github.io/interpolator/

3.写在最后

源码已托管到GitHub上,欢迎Fork,觉得还不错就Start一下吧!

GitHub地址:https://github.com/alidili/PropertyAnimationDemo

欢迎同学们吐槽评论,如果你觉得本篇博客对你有用,那么就留个言或者点下喜欢吧(^-^)

推荐阅读更多精彩内容