我们在做动画的时候,总是避免不了会使用到 Interpolator(插值器)这个东西,比如 LinearInterpolator 等。这样做的好处是,能够让动画的变化速度符合现实世界中的物理规律,看上去更加逼真。比如汽车启动时,速度总是越来越快的。

Android SDK 提供有多种插值器供开发人员使用。但很多时候,由于我们的英语水平、数学水平等原因,总是无法直观地区分各种插值器之间的细微区别。

无意中看到国外友人的一篇文章。这篇文章使用公式和图解的形式细细分析了各种插值器下的变化规律。于是翻译过来,希望这种图文并茂的方式能够让我们加深对不同插值器的理解。

这篇文章我将向你展示,如何定制属于你自己的动画插值器。就像前面文章所讲的,动画系统已经提供了一系列的插值器供你选择。但是有时候你会有不一样的需求,并且你希望你的插值器有些微的不同。你可以改变已有的插值器甚至创建你自己的插值器。在文章末尾,我将创建一个新的 HesitateInterpolator 插值器作为示范。这个插值器使得动画全速启动,然后减速到一半,再加速直到动画结束。但是在此之前,我先讲讲插值器的理论知识,并向你展示如何定制已有的系统插值器。

一点理论知识


想要知道如何实现一个插值器之前,我们必须理解一个插值器到底做了什么。动画在开始时间和结束时间之间执行,每一帧都在这期间的一个特定时间显示。这个特定时间就是一个时间指数,0.0 到 1.0 闭区间中的一个 float 类型的数字。0.0 表示动画开始,1.0 表示动画结束。最简单的场景是,这个值直接被用于计算动画执行对象的变化。这种情况下,0.0 对应着动画的起始位置,1.0 对应着结束位置,0.5 表示一半,即起始位置和中间位置的正中间。这就是 LinearInterpolator(线性插值器)所做的事情。时间变化 30%,View 对应移动 30% 的距离。

一般来说,这个时间指数并不是直接用来计算动画的变化值。我们可以改变时间指数的值,使其以其他值的方式也能从 0.0 走到 1.0,而不是按照固定不变的方式运行。这就是插值器所做的事情。

一个时间插值器基本上也是一个数学公式,从 0.0 到 1.0 之间取一个值,然后变化为另一个值。下图向我们展示了加速度插值器的变化规律。View 以零速度启动,然后朝着结束位置加速变化。

默认情况下,加速度插值器的数学公式使用的是:

y = t2

这里的 y 值表示插值器的输出值,t 值表示时间指数。加速度插值器可以通过一个参数实现定制化。通常,加速度插值器使用的这个公式这样表示:

y = t2f

f 作为一个因子,用于强调加速度的的变化。f 值越大,意味着 View 启动越慢,然后以更快的速度结束。另一方面,f 值为 1 时展示出的效果与线性插值器(Linear Interpolator)一致。

定制化插值器


大部分系统插值器都可以使用 XML 资源文件或者动态编程的方式实现定制化。通过 XML 资源定制化插值器的话,你必须在 res/anim 目录下创建一个新的 XML 文件。比如,我们想修改加速度插值器,设置 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" />

注意:指定插值器的标签使用的是对应插值器的类名,但是第一个字母改为小写字母。然后你就可以像平时那样,在动画资源文件中简单地通过引用方式使用这个自定义的插值器:

@anim/my_accelerate_interpolator

举个例子,在 Scale 动画中使用:

<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" />

插值器一览


Linear Interpolator(线性插值器)

类名:

LinearInterpolator

资源 id:

@android:anim/linear_interpolator

标签名:

linearInterpolator

数学公式:

y = t

类构造函数:

public LinearInterpolator()

属性:

Accelerate Interpolator(加速度插值器)

类名:

AccelerateInterpolator

资源 id:

@android:anim/accelerate_interpolator

标签名:

accelerateInterpolator

数学公式:

y = t2f

类构造函数:

public AccelerateInterpolator(float factor)

参数:

名称:f

属性:android:factor

描述:加速度的变化速率

值越大,动画初始移动速度越慢,然后以更快的速度运动至结束。

Decelerate Interpolator(减速度插值器)

类名:

DecelerateInterpolator

资源 id:

@android:anim/decelerate_interpolator

标签名:

decelerateInterpolator

数学公式:

y = 1 - (1 - t)2f

类构造函数:

public DecelerateInterpolator(float factor)

参数:

名称:f

属性:android:factor

描述:减速度的变化速率。

值越大,动画初始移动速度越快,然后以更慢的速度运动至结束。

Accelerate Decelerate Interpolator(先加速后减速插值器)

类名:

AccelerateDecelerateInterpolator

资源 id:

@android:anim/accelerate_decelerate_interpolator

标签名:

accelerateDecelerateInterpolator

数学公式:

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

类构造函数:

public AccelerateDecelerateInterpolator()

参数:

Anticipate Interpolator(张力加速器)

类名:

AnticipateInterpolator

资源 id:

@android:anim/anticipate_interpolator

标签名:

anticipateInterpolator

数学公式:

y = (T + 1) × t3 – T × t2

类构造函数:

public AnticipateInterpolator(float tension)

参数:

名称:T

属性:android:tension

描述:反向张力值,默认值为 2。

值越大,初始化反向张力越大,运动也越快

Overshoot Interpolator(越界加速器)

类名:

OvershootInterpolator

资源 id:

@android:anim/overshoot_interpolator

标签名:

overshootInterpolator

数学公式:

y = (T + 1) × (t - 1)3 + T × (t - 1)2 + 1

类构造函数:

public OvershootInterpolator(float tension)

参数:

名称:T

属性:android:tension

描述:越界数量值,默认值为 2。

值越大,越界越多,运动也越快

Overshoot Interpolator

类名:

AnticipateOvershootInterpolator

资源 id:

@android:anim/anticipate_overshoot_interpolator

标签名:

anticipateOvershootInterpolator

数学公式:



类构造函数:

- public AnticipateOvershootInterpolator(float tension)

- public AnticipateOvershootInterpolator(float tension, float extraTension)

参数:

属性:android:tension

描述:越界数量值,默认值为 2。

值越大,越界越多,运动也越快

属性:android:extraTension

描述:额外反向张力值,默认值为 1.5。

T 值为:tension * extraTension

Bounce Interpolator(弹性插值器)

类名:

BounceInterpolator

资源 id:

@android:anim/bounce_interpolator

标签名:

bounceInterpolator

数学公式:



类构造函数:

public BounceInterpolator()

参数:

* Cycle Interpolator*(弹性插值器)

类名:

Cycle Interpolator

资源 id:

@android:anim/cycle_interpolator

标签名:

cycleInterpolator

数学公式:

y = sin(2π × C × t)

类构造函数:

public CycleInterpolator(float cycles)

参数:

名称:C

属性:android:cycles

描述:循环次数,默认值为 1.

创建新的插值器


正如上面所言,插值器本质上展示的是一个数学公式。要想创建一个属于你自己的插值器类,你必须实现 Interpolator 接口。这个接口只定义了一个方法:

float getInterpolation(float t) 

用于公式中的计算。举个例子,我想创建一个名为 HesitateInterpolator 的插值器,动画以最快的速度启动,然后减速运动至一半,最后加速运动至结束。运动曲线如图所示:

对应数学公式为:

y=0.5 × ((2t − 1)3+1)

HesitateInterpolator 类的代码也很简单:

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);
  }
}

使用这个插值器时,你只需要通过动态编程的方式将其添加到你的 View 动画中去:

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

就是这些!不需要任何额外代码。

不幸的事,你不能在 XML 动画资源中使用这个插值器,只支持动态编程的方式。

GIF 图效果


上面所述便是翻译原文的全部部分。最后再附上几张 Gif 图,也来自国外友人的博客,通过对比的形式更加直观地查看不同插值器的作用效果:

  • Accelerate Decelerate, Accelerate, Anticipate & Anticipate Overshoot:

  • Bounce, Decelerate, Fast Out Linear In & Fast Out Slow In:

  • Fast Out Slow In, Linear, Linear Out Slow In & Overshoot

参考链接


英文原文:Android Animations Tutorial 5: More on Interpolators

Gif 图来源:Android Interpolators: A Visual Guide

关于我:亦枫,博客地址:http://yifeng.studio/,新浪微博:IT亦枫

微信扫描二维码,欢迎关注我的个人公众号:安卓笔记侠

不仅分享我的原创技术文章,还有程序员的职场遐想

【译】从数学公式入手,详细了解 Animation 的 Interpolators的更多相关文章

  1. 2018年1月17日总结 css3里transition 和animation 区别

    transition 和animation两个CSS3属性经常被用到实际项目中,想把它整理出来. 1.先介绍transition >>>>>  a. 在做项目中经常会遇见 ...

  2. 11.IntelliJ IDEA详细配置和使用教程(适用于Java开发人员)

    转自:https://blog.csdn.net/chssheng2007/article/details/79638076 前言 正所谓工欲善其事必先利其器,对开发人员而言若想提高编码效率,一款高效 ...

  3. IntelliJ IDEA详细配置和使用教程(适用于Java开发人员)

    关闭Intellij IDEA自动更新在File->Settings->Appearance & Behavior->System Settings->Updates下 ...

  4. Java 在Word中添加数学公式(Latex/MathML)

    本文介绍通过Java程序在Word文档中添加数学公式的方法.添加时,可添加latex数学公式或者MathML数学公式.详细内容见下文. 1. 程序环境 Word测试文档:.docx 2013 Word ...

  5. 一篇博客带你入门Flask

    一. Python 现阶段三大主流Web框架 Django Tornado Flask 对比 1.Django 主要特点是大而全,集成了很多组件,例如: Models Admin Form 等等, 不 ...

  6. android 属性动画

    一直再追郭霖的博客和imooc上的一些新的视频,最近有讲到属性动画. 以下内容为博客学习以及imooc上视频资料的学习笔记: 在3.0之前比较常见的动画为tween动画和frame动画: tween动 ...

  7. babel如此简单

    凡是看到这个标题点进来的同学,相信对babel都有了一定的了解.babel使用起来很简单,简单到都没有必要写一篇文章去介绍,直接看看官方文档就可以.所以我也在怀疑到底该不该写这篇文章.想来想去还是决定 ...

  8. babel从入门到入门

    babel从入门到入门 来源 http://www.cnblogs.com/gg1234/p/7168750.html 博客讲解内容如下: 1.babel是什么 2.javascript制作规范 3. ...

  9. babel简介

    1.babel是什么 babel官网正中间一行黄色大字写着“babel is a javascript compiler”,翻译一下就是babel是一个javascript转译器.为什么会有babel ...

随机推荐

  1. 自制mysql的rpm包

    MySQL安装一般使用RPM或者源码安装的方式.RPM安装的优点是快速,方便.缺点是不能自定义安装目录.如果需要调整数据文件和日志文件的存放位置,还需要进行一些手动调整.源码安装的优点是可以自定义安装 ...

  2. Ubuntu 12.04下安装QQ 2012 Beta3

    Ubuntu 12.04下安装QQ 2012 Beta3   由于wine的发展非常迅速.现在网上的利用老版本的wine来安装QQ2012的教程已经有些过时了.实际上操作起来非常简单: 第一步:Ctr ...

  3. Linux下安装SVN服务端

    安装 使用yum安装非常简单: yum install subversion 配置 2.1. 创建仓库 我们这里在/home下建立一个名为svn的仓库(repository),以后所有代码都放在这个下 ...

  4. creator cocos2d-js-min.js 文件廋身 变小 太大解决方法

    使用的 cocos creator 1.2 版本, 菜单栏 项目 -- 项目设置 -- 模块设置 里面 把不要的模块去掉

  5. Scrapyd 项目爬虫部署

    scrapyd是一个用于部署和运行scrapy爬虫的程序,它允许你通过JSON API来部署爬虫项目和控制爬虫运行 scrapyd是一个守护进程,监听爬虫的运行和请求,然后启动进程来执行它们 安装扩展 ...

  6. [BZOJ3174]拯救小矮人

    Description 一群小矮人掉进了一个很深的陷阱里,由于太矮爬不上来,于是他们决定搭一个人梯.即:一个小矮人站在另一小矮人的 肩膀上,知道最顶端的小矮人伸直胳膊可以碰到陷阱口.对于每一个小矮人, ...

  7. mybatis动态sql中的bind绑定

    知识点:bind在模糊查询中的用法 在我的博客    mybatis中使用mysql的模糊查询字符串拼接(like) 中也涉及到bind的使用 <!-- List<Employee> ...

  8. DBUS及常用接口介绍

    [原文]  1. 概述 1.1  DBUS概述     DBUS是一种高级的进程间通信机制.DBUS支持进程间一对一和多对多的对等通信,在多对多的通讯时,需要后台进程的角色去分转消息,当一个进程发消息 ...

  9. php中点击下载按钮后待下载文件被清空

    在php中设置了文件下载,下载按钮使用表单的方式来提交 <form method="post" class="form-inline" role=&quo ...

  10. 使用百度地图LBS创建自定义标注

    <body> <div id="allmap"></div> <div class="sel_container" i ...