Android动画全篇系列(三)——插值器

一、插值器(Interpolator)介绍

插值器是帮助定义动画变化率的接口,即加速动画、减速动画、重复动画等。

在上一章我们了解到补间动画有一个设置插值器的方法:anim.setInterpolator(Interpolator i)

Interpolator是一个接口,那么我们翻翻他有多少个实现:
继承关系

二、实现

我们可以看到系统已经存在很多个可以直接使用的插值器,我们随便挑一个来使用,使用的方法非常的简单:

  1. 挑一个幸运插值器(OvershootInterpolator)
  2. 调用anim.setInterpolator(OvershootInterpolator()),直接new一个就行了。
    效果
    可以发现动画会先是超过了原本“最终帧”的位置,然后又慢慢的回弹。

三、示例

我从网上找到几张图,可以提供参考:
参考1
参考2
参考3

四、自定义插值器

官方提供的插值器基本都会满足我们的需求,但是如果你怎样都觉得不满意,这个动画就是看着不爽!怎么办?那就只能去自定义一个插值器,来满足自己的需求(另外你还需要恨自信你的数学)。

1、 既然要自定义插值器,那么我们就创建一个类来继承 Interpolator接口:
class MyInterpolator : Interpolator {
    override fun getInterpolation(input: Float): Float {
        
    }
}

因为是个接口,所以必须实现其方法,好在只有一个方法需要改造。

万事开头难啊!
难

2、我们只能先参考官方是怎么实现的,挑一个幸运插值器(LinearInterpolator)来研究以下:
    public float getInterpolation(float input) {
        return input;
    }

懵逼
很简单,你给啥我返回啥~

3、赶紧查看官网作何解释吧!
  1. 有两个关键的值:给我们的input 和 输出给别人用的返回值。两个都是float类型的。
  2. input取值范围为[0,1],当值为0代表动画要开始了,当值为1代表动画结束了。
  3. 返回值可以是小于0,也可以大于1,越值了表示动画也会越过去,就像我们之前OvershootInterpolator的示例一样。
  4. 这个方法将表示动画经过部分的值映射到表示插值部分的值。然后将该插值乘以动画值的变化,以在当前经过的动画时间导出动画值。

前面三点我相信你们都看懂,最后一点肯定是一脸懵逼的~
没关系!我们结合LinearInterpolator就不难猜出,真正反映动画播放效果的就是我们要返回的值!

4、Demo

为此,我们来模仿以下LinearInterpolator做个简单的小例子:

 override fun getInterpolation(input: Float): Float {
        if (input>0.8){
            return (input+0.2).toFloat();
        }
        return input
    }
  1. 当动画播放到4/5之前,我们直接返回input,表示直线运行。
  2. 当动画播放到4/5之后,我们返回input+0.2,看看他会怎样。
    坏笑
    画面
    我们发现,前面还好好的,匀速播放,等接近尾声的时候,突然跳动了!
5、小结

经过上面的分析,不难发现,插值器的关键之处,就在于如何操作
fun(input):Float 值,再返回其结果,就是动画最终的实现效果。
还记得我们之前说过,你还需要很自信你的数学,这是怎么个说法呢?我们直接看看官方其他的实现,你就明白了!
坏笑

//OvershootInterpolator

	private final float mTension;

    public OvershootInterpolator() {
        mTension = 2.0f;
    }
    
    public OvershootInterpolator(float tension) {
        mTension = tension;
    }
    
	public float getInterpolation(float t) {
        // _o(t) = t * t * ((tension + 1) * t + tension)
        // o(t) = _o(t - 1) + 1
        t -= 1.0f;
        return t * t * ((mTension + 1) * t + mTension) + 1.0f;
    }
	//AccelerateInterpolator
	private final float mFactor;
    private final double mDoubleFactor;

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

看见了吧,没有好的数学功底,你别瞎参活了~

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值