原文来自于:Android Animations Tutorial 5: More on Interpolators


译者注:这篇文章是一系列动画教程中的一篇,对Android内置的几种Interpolator(插值器)讲解得非常清楚,特作翻译,其他几篇文章有空也可以考虑翻译。这一系列的文章依次是:

Android Animations Tutorial 1: Introduction 

Android Animations Tutorial 2: View Animations Overview 

Android Animations Tutorial 3: Customising Animations 

Android Animations Tutorial 4: Programming View Animations 

Android Animations Tutorial 5: More on Interpolators 

Android Animations Tutorial 6: Animation Sets and Start Offset 

Android Animations Tutorial 7: The secret of fillBefore, fillAfter and fillEnabled

相关概念

在动手实现自定义Interpolator之前,我们需要明白其背后的原理和概念。动画的基本原理是从开始时间到结束时间一帧一帧地播放静态图像,如果我们用0.0表示动画的开始时间点,用1.0表示动画的结束时间点,则动画时间轴上的每个点都可以转换成0.0到1.0之间的一个浮点数,本文中我们称为Time Index。比如,动画中间的时间点可以用0.5来表示。对于使用了LinearInterpolator(线性插值器)的平移动画来讲,在0.3这个时间点视图则刚好移动了整个动画的30%。


我们一般不会将Time Index直接带入到动画计算公式,这也是Interpolator的存在的意义。

wKiom1OfAomyMDR-AAA6n23bvAw712.jpg

从本质上来讲,Interpolator是一种数学函数,参数是0.0到1.0之间的浮点数,输出也是一个浮点数。如上图所示,这是一个AccelerateInterpolator(加速插值器)的图。目标对象的起始速度是0,然后逐渐增大(译者注:曲线的斜率是速度)。默认情况下,可以用下面的表达式来表示:

y = t^2

这里的y就是Interpolator的输出,t是Time Index。我们可以增加一个参数来对AccelerateInterpolator的行为进行自定义:

y = t ^(2f)

这里的f越大,起始速度越慢,但是后期加速度会更大;如果f=0.5,则和LinearInterpolator的行为一模一样了。

配置Inerpolators

很多Interpolator都可以通过XML或者编程的方式来设置参数。通过XML方式需要在res/anim文件夹里面创建一个XML文件。比如,你想将AccelerateInterpolator的f参数设置为2,你可以创建这样一个文件

res/anim/my_accelerate_interpolator.xml,其内容如下:

<?xml version="1.0" encoding="utf-8"?>
<accelerateInterpolator
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:factor="2" />

注意,accelerateInterpolator表示这是一个AccelerateInterpolator,第一个字符小写。


创建了这个文件后,你可以在通过@anim/my_accelerate_interpolator来使用这个Interpolator。比如下面这个缩放的动画效果:

<scale xmlns:android="http://schemas.android.com/apk/res/android"
        android:interpolator="@anim/my_accelerate_interpolator"
        android:fromXScale="0.0"
        android:toXScale="1.0"
        android:fromYScale="0.0"
        android:toYScale="1.0"
        android:duration="300" />

Interpolator概览

1. Linear Interpolator / 线性插值器

类名: LinearInterpolator

资源ID: @android:anim/linear_interpolator

XML标记: linearInterpolator

公式: y=t

构造函数: public LinearInterpolator()

属性: 无

wKioL1OfBX2i24iLAACVw04NLps987.jpg

2. Accelerate Interpolator / 加速度插值器

类名: AccelerateInterpolator

资源ID: @android:anim/accelerate_interpolator

XML标记: accelerateInterpolator

公式: y=t^(2f)

构造函数: public AccelerateInterpolator(float factor)

参数:

    名称: f

    XML属性: android:factor

    描述: 加速度参数. f越大,起始速度越慢,但是速度越来越快

wKioL1OfBg7RSunbAAEfeaz5sDM514.jpg

3. Decelerate Interpolator / 减速插值器

类名: DecelerateInterpolator

资源ID: @android:anim/decelerate_interpolator

XML标记: decelerateInterpolator

公式: y=1-(1-t)^(2f)

构造函数: public DecelerateInterpolator(float factor)

参数:

    名称: f

    XML属性: android:factor

    描述: 加速度参数.  f越大,起始速度越快,但是速度越来越慢


wKiom1OfBajjXqiMAAEhQLqnW7c574.jpg

4. Accelerate Decelerate Interpolator / 先加速后减速插值器

类名: AccelerateDecelerateInterpolator

资源ID: @android:anim/accelerate_decelerate_interpolator

XML标记: accelerateDecelerateInterpolator

公式: y=cos((t+1)π)/2+0.5

构造函数: public AccelerateDecelerateInterpolator()

参数: 无

wKioL1OfBXviFOI8AACS1BUkSAc421.jpg

5. Anticipate Interpolator

类名: AnticipateInterpolator

资源ID: @android:anim/anticipate_interpolator

XML标记: anticipateInterpolator

公式: y=(T+1)×t^3–T×t^2

构造函数: public AnticipateInterpolator(float tension)

参数:

    名称: T

    XML属性: android:tension

    描述: 张力值, 默认为2,T越大,初始的偏移越大,而且速度越快

wKiom1OfBajRBsJJAAETcvHNUBE521.jpg

6. Overshoot Interpolator

类名: OvershootInterpolator

资源ID: @android:anim/overshoot_interpolator

XML标记: overshootInterpolator

公式: y=(T+1)x(t1)^3+T×(t1)^2 +1

构造函数: public OvershootInterpolator (float tension)

参数:

    名称: T

    XML属性: android:tension

   描述: 张力值,默认为2,T越大,结束时的偏移越大,而且速度越快

wKioL1OfBXuhcPNnAAEOoi-2cW4445.jpg

7. Anticipate Overshoot Interpolator

类名: AnticipateOvershootInterpolator

资源ID: @android:anim/anticipate_overshoot_interpolator

XML标记: anticipateOvershootInterpolator

公式:

wKioL1OfC22RgSlMAABoTvVneig089.jpg

构造函数:

public AnticipateOvershootInterpolator(float tension)

public AnticipateOvershootInterpolator(float tension, float extraTension)

参数:

    XML属性: android:tension

    描述: 张力值,默认为2,张力越大,起始和结束时的偏移越大,而且速度越快

    XML属性: android:extraTension

    描述: 额外张力值,默认为1.5。公式中T的值为tension*extraTension

wKiom1OfBajzrFbnAADZ0xYSpt8664.jpg

8. Bounce Interpolator / 弹跳插值器

类名: BounceInterpolator

资源ID: @android:anim/bounce_interpolator

XML标记: bounceInterpolator

公式: 

wKiom1OfCynDRnvhAADOnd02em0121.jpg


构造函数: public BounceInterpolator ()

参数: 无


wKiom1OfBaiiarvZAACscX-uQmE120.jpg

9. Cycle Interpolator / 周期插值器

类名: CycleInterpolator

资源ID: @android:anim/cycle_interpolator

XML标记: cycleInterpolator

公式: y=sin(2π×C×t)

构造函数: public CycleInterpolator(float cycles)

参数:

    名称: C

    XML属性: android:cycles

   描述: 周期值,默认为1;2表示动画会执行两次

wKioL1OfBXrQcMwtAAGa9t3aYx4374.jpg

创建自定义Interpolators

下面,我们就来创建自己的Interpolator。上面已经讲得非常清楚了,Interpolator的关键在于公式。我想创建的Interpolator名字叫HesitateInterPolator:起始时速度全速,快到一半时减速到0,然后加速直到终点,用图形来表示即:

wKiom1OfdjbiHyniAACO8liEKxU986.jpg

用数学公式来表示即:

wKioL1OfdlDyqOUVAAAac5qaISI552.jpg

我们只需要实现Interpolator接口,然后实现其中的float getInterpolation(float t)接口即可:

public class HesitateInterpolator implements Interpolator {
    public HesitateInterpolator() {}
    public float getInterpolation(float t) {
      float x=2.0f*t-1.0f;
      return 0.5f*(x*x*x + 1.0f);
    }
}

通过编程方式来使用自定义Interpolator很简单,比如:

ScaleAnimation scale = new ScaleAnimation(0.0f, 1.0f, 0.0f, 1.0f);
scale.setInterpolator(new HesitateInterpolator());

这样就好了。遗憾的是,我们无法在XML资源中使用自定义Interpolator。