Android-Interpolator介绍

738 阅读2分钟

Interpolator,意译插值器,我理解为android中的变速器,依据数学中的函数公式比如y=axy=ax计算获得想要的值,通常情况下,x为随时间固定变化的、取值0-1的小数,y为进度,取值0 - 1,a为任意参数。

以下是相关源码分析。

TimeInterpolator

顺着任意插值器可以找到最初的父接口,android.animation.TimeInterpolator,从名字就可看出:随时间变化的插值器。内部提供了 getInterpolation()方法,提供了最基本的需求。

// 入参input: 时间参数,取值0-1,0代表开始,1代表结束
// 返回值float: 进度
float getInterpolation(float input);

Interpolator

从文档中看到,android.view.animation.Interpolator 继承自TimeInterpolator接口,没有其他任何方法,仅仅是为了描述动画改变速率的抽象接口而已。其实直接去掉也没事,为什么要有这个中间接口呢?因为这个接口很古老,Android诞生的时候就引入了,而TimeInterpolator是在Android Api11的时候引入的,我猜想是为了兼容老版本,所以Interpolator没有直接删除,而是采用了继承,代代传了下来。如Interpolator的注释所写:

public interface Interpolator extends TimeInterpolator {
    // A new interface, TimeInterpolator, was introduced for the new android.animation
    // package. This older Interpolator interface extends TimeInterpolator so that users of
    // the new Animator-based animations can use either the old Interpolator implementations or
    // new classes that implement TimeInterpolator directly.
}

BaseIntorpolator

android.view.animation.BaseInterpolator,Interpolator的抽象类,添加了一个抽象参数:mChangingConfiguration。相当于我们上面数学公式中 y = ax中的a,不怎么常用,了解即可。


LinearInterpolator

线性插值器,输入即输出:

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

企业微信20220419-131846@2x.png


DecelerateInterpolator

减速插值器,速度越来越慢

private float mFactor = 1.0f;

public float getInterpolation(float input) {
    float result;
    if (mFactor == 1.0f) {
        result = (float)(1.0f - (1.0f - input) * (1.0f - input));
    } else {
        result = (float)(1.0f - Math.pow((1.0f - input), 2 * mFactor));
    }
    return result;
}

减速.png


AccelerateInterpolator

加速插值器,速度越来越快

private static float mFactor = 1.0f;
private static double mDoubleFactor = 2.0;

public static  float getInterpolation(float input) {
    if (mFactor == 1.0f) {
        return input * input;
    } else {
        return (float)Math.pow(input, mDoubleFactor);
    }
}

加速.png


AccelerateDecelerateInterpolator

换挡插值器,先加速后减速

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

换挡.png


AnticipateInterpolator

回手抛插值器,先后抛,然后迅速前抛

int tension = 2
public float getInterpolation(float t) {
    // a(t) = t * t * ((tension + 1) * t - tension)
    return t * t * ((mTension + 1) * t - mTension);
}

后抛前抛.png


BounceInterpolator

弹珠插值器,像掉落在地板装上的玻璃球,弹跳高度越来越小

private static float bounce(float t) {
    return t * t * 8.0f;
}

public float getInterpolation(float t) {
    // _b(t) = t * t * 8
    // bs(t) = _b(t) for t < 0.3535
    // bs(t) = _b(t - 0.54719) + 0.7 for t < 0.7408
    // bs(t) = _b(t - 0.8526) + 0.9 for t < 0.9644
    // bs(t) = _b(t - 1.0435) + 0.95 for t <= 1.0
    // b(t) = bs(t * 1.1226)
    t *= 1.1226f;
    if (t < 0.3535f) return bounce(t);
    else if (t < 0.7408f) return bounce(t - 0.54719f) + 0.7f;
    else if (t < 0.9644f) return bounce(t - 0.8526f) + 0.9f;
    else return bounce(t - 1.0435f) + 0.95f;
}

弹珠.png


AnticipateOvershootInterpolator

回抛越界插值器

private static float mTension = 3.5f;


public static float getInterpolation(float t) {
    if (t < 0.5f) return 0.5f * a(t * 2.0f, mTension);
    else return 0.5f * (o(t * 2.0f - 2.0f, mTension) + 2.0f);
}

private static float a(float t, float s) {
    return t * t * ((s + 1) * t - s);
}

private static float o(float t, float s) {
    return t * t * ((s + 1) * t + s);
}

回抛越界.png


CycleInterpolator

周期插值器,内部有一个成员变量:mCycles,默认值1,是指x=1时,sin函数完整的走完了1个周期。举例,mCycles = 0.1时,x=1时,sin函数只能走完十分之一。mCycles=0.5时,x=1时,sin函数只能走完一半。

private float mCycles = 0.5f; // 以0.5举例

public float getInterpolation(float input) {
    return (float)(Math.sin(2 * mCycles * Math.PI * input));
}

周期函数.png


PathInterpolator

路径插值器。前面说的插值器都是根据函数一点一点计算出来的,路径插值器是根据我们自己提供的point来计算的,有兴趣的可以先去了解一下贝塞尔曲线,很有意思。

收集相关网址: