Android动画之插值器简介和系统默认插值器

1 插值器(Interpolator)简介

插值器(Interpolator)是设置动画运行过程中的变化规律,类似匀速变化,加速变化,回弹等。
补间动画Animation设置插值器的两个函数:

public void setInterpolator(Context context, @AnimRes @InterpolatorRes int resID) ;
public void setInterpolator(Interpolator i) ;

xml动画配置文件中设置插值器代码:
android:interpolator="@android:anim/linear_interpolator"

上面的setInterpolator函数和 android:interpolator属性就是设置动画的插值器。

实际使用动画过程中,有时可能不完全都是要求动画匀速运动,类似加速运动,仿抛物线运动等,都需要插值器的配合。

2系统提供的默认插值器

可以看到除了BaseInterpolator(抽象类,不讨论)外有10种系统提供的插值器。下面从xml中引用插值器的字段和插值器对应的具体类和插值器的作用三方面来介绍系统提供的插值器。

  • @android:anim/linear_interpolator 对应 LinearInterpolator
    作用:动画匀速改变

  • @android:anim/decelerate_interpolator 对应 DecelerateInterpolator
    作用:动画运行越来越慢,减速运行 ,说明开始的时候是最高速。

  • @android:anim/accelerate_interpolator 对应 AccelerateInterpolator
    作用:动画加速进行,动画开始运行时变化很慢,越到后面越快,最后突然结束。

  • @android:anim/accelerate_decelerate_interpolator 对应java类AccelerateDecelerateInterpolator
    作用 :动画先加速再减速,相当于view速度从0一直加速,最后又减速到0,默认插值器。

  • @android:anim/anticipate_interpolator 对应 AnticipateInterpolator
    作用:先退后再加速前进 ,类似投掷标枪,先往后一点,然后加速运行。

  • @android:anim/anticipate_overshoot_interpolator 对应java类AnticipateOvershootInterpolator
    作用:先退后再加速前进,超出终点后再回终点

  • @android:anim/bounce_interpolator 对应 BounceInterpolator
    作用:最后阶段弹球效果,就是会在到达终点后,类似弹球回弹几次。

  • @android:anim/cycle_interpolator 对应CycleInterpolator
    作用:周期运动,动画可以不到终点就回弹,也可以到了终点后在回弹,还可以回弹多次,小于1.0f不到终点就回弹,大于1.0f会到了终点后回弹,如果大于2,则会回弹多次。下面的例子会设置5次,大家可以看效果。

  • @android:anim/overshoot_interpolator 对应 OvershootInterpolator
    作用:快速完成动画,会超出一点然后再回到结束样式。

  • @android:anim/path_interpolator 对应 PathInterpolator,
    作用:根据路径来控制动画的执行快慢,路径可以是贝塞尔曲线,也可以是普通Path。

系统提供的插值器里前面的九个都比较简单,只有最后一个PathInterpolator,是api21添加的新的插值器,而且其有三个构造函数,相对较复杂会单独讲解。

3 插值器的使用

如何使用插值器
xml动画文件,直接指定
XML动画文件使用插值器时,需要设置系统设置的对应的插值器资源ID,上面已给出。

java代码中两种方式:
Java代码使用插值器时,只需创建对应的插值器对象,然后设置给动画对象;也可以加载xml文件中配置的插值器。然后利用view的setInterpolator(Context context, @AnimRes @InterpolatorRes int resID)设置插值器。

xml设置插值器例子:

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

代码演示插值器

这里只用Translate动画来演示插值器的效果:

<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromXDelta="-300"
    android:toXDelta="500"
    android:fromYDelta="-300"
    android:toYDelta="1000"
    android:duration="3000"
    android:fillBefore="true">
</translate>
@Override
public void onClick(View v) {
    switch (v.getId()){
        case R.id.btn1:
            if (imageView.getAnimation() != null && !imageView.getAnimation().hasEnded()){
                imageView.getAnimation().cancel();
            }
                mTranslateAnimation.setInterpolator(new AccelerateInterpolator());
                imageView.startAnimation(mTranslateAnimation);
            break;
        case R.id.btn2:
            if (imageView.getAnimation() != null && !imageView.getAnimation().hasEnded()){
                imageView.getAnimation().cancel();
            }
            mTranslateAnimation.setInterpolator(new DecelerateInterpolator());
            imageView.startAnimation(mTranslateAnimation);
            break;
        case R.id.btn3:
            if (imageView.getAnimation() != null && !imageView.getAnimation().hasEnded()){
                imageView.getAnimation().cancel();
            }
            mTranslateAnimation.setInterpolator(new AccelerateDecelerateInterpolator());
            imageView.startAnimation(mTranslateAnimation);
            break;
        case R.id.btn4:
            if (imageView.getAnimation() != null && !imageView.getAnimation().hasEnded()){
                imageView.getAnimation().cancel();
            }
            mTranslateAnimation.setInterpolator(new LinearInterpolator());
            imageView.startAnimation(mTranslateAnimation);
            break;
        case R.id.btn5:
            if (imageView.getAnimation() != null && !imageView.getAnimation().hasEnded()){
                imageView.getAnimation().cancel();
            }
            mTranslateAnimation.setInterpolator(new AnticipateInterpolator());
            imageView.startAnimation(mTranslateAnimation);
            break;
        case R.id.btn6:
            if (imageView.getAnimation() != null && !imageView.getAnimation().hasEnded()){
                imageView.getAnimation().cancel();
            }
            mTranslateAnimation.setInterpolator(new OvershootInterpolator());
            imageView.startAnimation(mTranslateAnimation);
            break;
        case R.id.btn7:
            if (imageView.getAnimation() != null && !imageView.getAnimation().hasEnded()){
                imageView.getAnimation().cancel();
            }
            mTranslateAnimation.setInterpolator(new AnticipateOvershootInterpolator());
            imageView.startAnimation(mTranslateAnimation);
            break;
        case R.id.btn8:
            if (imageView.getAnimation() != null && !imageView.getAnimation().hasEnded()){
                imageView.getAnimation().cancel();
            }
            mTranslateAnimation.setInterpolator(new BounceInterpolator());
            imageView.startAnimation(mTranslateAnimation);
            break;
        case R.id.btn9:
            if (imageView.getAnimation() != null && !imageView.getAnimation().hasEnded()){
                imageView.getAnimation().cancel();
            }
            mTranslateAnimation.setInterpolator(new CycleInterpolator(5));
            imageView.startAnimation(mTranslateAnimation);
            break;
    }
}
image

4 PathInterpolator 路径插值器

image

作用说明:
路径插值器在动画运行过程中,会遍历整个路径,路径必须从(0,0)开始到(1,1)点结束。它会在一个1*1的坐标系内部指定动画的运动轨迹,路径可以是贝塞尔曲线或者是普通的path。

兼容版本可以用PathInterpolatorCompat类,在v4包中。

构造函数:
PathInterpolator(Path path):利用Path构造插值器。
PathInterpolator(float controlX, float controlY):传入一个控制点,构造二维贝塞尔曲线插值器。
PathInterpolator(float controlX1, float controlY1, float controlX2, float controlY2):传入两个控制点,构造三维贝塞尔曲线插值器。
PathInterpolator(Context context, AttributeSet attrs),加载xml定义的插值器。

其中X坐标轴表示时间进度,动画进行了多长时间,0表示刚开始,1表示动画运行完了。
Y坐标表示动画完成程度,0表示动画初始状态,0.5表示动画完成一半时的状态,1表示动画结束时的状态。

举个例子:
Path path = new Path();
path.lineTo(0.25f, 0.25f);
path.moveTo(0.25f, 0.5f);
path.lineTo(1f, 1f);

解释:上面的代码生成的PathInterpolator得含义为,首先按照动画完成度和时间1:1的比例,在1/4的时间内达到动画完成1/4的效果,然后突然让动画变成完成1/2的状态此时动画运行时间依然才过了1/4,然后在接下来的时间让动画运行到结束,状态也变成动画结束后的状态。所以展示的效果就是先匀速变化,然后突然变化,然后在匀速变化。
示意图:

image

贝塞尔曲线的应用

PathInterpolator(float controlX, float controlY) 传入一个控制点,这个函数内部会生成贝塞尔曲线,就可以生成对应的插值器。

PathInterpolator pathInterpolator = new PathInterpolator(0.9f, 0.1f);
mTranslateAnimation.setInterpolator(pathInterpolator);
imageView.startAnimation(mTranslateAnimation);
<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromXDelta="-300"
    android:toXDelta="500"
    android:fromYDelta="-300"
    android:toYDelta="1000"
    android:duration="3000"
    android:fillBefore="true">
</translate>

时间与速度变化示意图,从贝塞尔曲线可以看出首先动画变化速度缓慢,然后大概动画运行了80%时快速完成动画。


5 support v4 包中新提供的插值器

FastOutLinearInInterpolator ,FastOutSlowInInterpolator,LinearOutSlowInInterpolator,这三个是在v4 22.1.0中添加的动画插值器,基本原理和PathInterpolator一样,都是利用贝塞尔曲线来描述动画运行过程。

FastOutLinearInInterpolator 效果和AccelerateInterpolator 类似,都是一个持续加速的运动路线,只是刚开始阶段LinearOutSlowInInterpolator更快。
FastOutSlowInInterpolator 是先加速再减速,类似AccelerateDecelerateInterpolator ,但FastOutSlowInInterpolator 前期比AccelerateDecelerateInterpolator 快很多。

LinearOutSlowInInterpolator 和DecelerateInterpolator 的效果类似。

FastOutLinearInInterpolator举例:

FastOutLinearInInterpolator fastOutLinearInInterpolator = new FastOutLinearInInterpolator();
mTranslateAnimation.setInterpolator(fastOutLinearInInterpolator);
imageView.startAnimation(mTranslateAnimation);
image

Animation动画概述和执行原理
Android动画之补间动画TweenAnimation
Android动画之逐帧动画FrameAnimation
Android动画之插值器简介和系统默认插值器
Android动画之插值器Interpolator自定义
Android动画之视图动画的缺点和属性动画的引入
Android动画之ValueAnimator用法和自定义估值器
Android动画之ObjectAnimator实现补间动画和ObjectAnimator自定义属性
Android动画之ObjectAnimator中ofXX函数全解析-自定义Property,TypeConverter,TypeEvaluator
Android动画之AnimatorSet联合动画用法
Android动画之LayoutTransition布局动画
Android动画之共享元素动画
Android动画之ViewPropertyAnimator(专用于view的属性动画)
Android动画之Activity切换动画overridePendingTransition实现和Theme Xml方式实现
Android动画之ActivityOptionsCompat概述
Android动画之场景变换Transition动画的使用
Android动画之Transition和TransitionManager使用
Android动画之圆形揭露动画Circular Reveal
Android 动画之 LayoutAnimation 动画
Android动画之视图动画的缺点和属性动画的引入

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,133评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,682评论 3 390
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,784评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,508评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,603评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,607评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,604评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,359评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,805评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,121评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,280评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,959评论 5 339
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,588评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,206评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,442评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,193评论 2 367
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,144评论 2 352

推荐阅读更多精彩内容

  • 【Android 动画】 动画分类补间动画(Tween动画)帧动画(Frame 动画)属性动画(Property ...
    Rtia阅读 6,135评论 1 38
  • 1 背景 不能只分析源码呀,分析的同时也要整理归纳基础知识,刚好有人微博私信让全面说说Android的动画,所以今...
    未聞椛洺阅读 2,701评论 0 10
  • 一: 传统 View 动画(Tween/Frame) 1.1 Tween 动画 主要有 4 中:缩放、平移、渐变、...
    dfg_fly阅读 716评论 1 2
  • 【书 目】《象与骑象人》 【课程领拆】赵周老师 【上课时间】2017年9月5日 【作 业】 1、A2:未来一...
    今夕何夕_斯阅读 276评论 0 0
  • 我是刚子(张志刚),专注零担物流15年,坚持每天写作第153天,《做一个有思想的物流人》作者,励志打造零担物流培训...
    有思想的物流快递人阅读 639评论 0 1