属性动画

学习,参考加部分信息拷贝,来自以下链接:
动画原理讲解系列:
http://blog.csdn.net/u013478336/article/details/52137385
牛逼的自定义插值器:
http://www.cnblogs.com/wondertwo/p/5327586.html
Evaluator
http://wiki.jikexueyuan.com/project/android-animation/5.html
http://wiki.jikexueyuan.com/project/android-animation/6.html 讲evaluator字母的变化
牛逼的动画原理讲解,但是没有仔细看的:
http://www.jianshu.com/p/ee7e3d79006d
其他:
http://www.jianshu.com/p/733532041f46
http://blog.csdn.net/lmj623565791/article/details/38067475/

概述

1.1 简述
属性动画引入自Android 3.0(API 11),其原理是给定对象的一个或多个属性,指定其开始与结束时的值,通过时间插值生成不同的属性值,并调用更新方法将属性值设置到对象内,引起对象重绘,从而形成动画效果。比如,通过不断的设置View的宽高来更新View的展示,形成缩放效果等。

1.2 属性动画相关概念
一个属性动画执行需要的基本要素包括:承载动画执行的对象属性、动画持续时间和属性的变化区间。

  • Duration: 指定动画的执行时间,默认300ms
  • Time interpolation: 一个输入为动画真实时间的函数,以此函数来计算动画属性;其实重点在于函数上,这个函数定义的是动画的变化速率,举个例子来看:假如有个函数y=x,x是动画的真实执行时间,y是映射后的速度,则这个动画是恒速执行的;假如映射函数是y=x*x,这个动画是就是不断加速运行的,因为y的变化速率在不断的增大。
  • Repeat count and behavior: 动画重复次数表示动画需要被执行的次数,动画重复时的行为有两种:从头开始或者反转执行;在动画执行结束时,如果没有执行完指定次数,则继续执行;
  • Animator sets: 将多个动画效果组成动画集合并设置彼此间的执行顺序,可设三种执行顺序:一起执行、顺序执行和在指定时间执行。
  • Frame refresh delay: 指定多长时间刷新一次动画的帧,默认值是10ms一次,但最终取决于当前系统的繁忙程度和系统多快能相应定时器,基本上我们可以不用考虑。
  • 监听动画: 开始 / 结束 / 重复时刻
anim.addListener(new AnimatorListenerAdapter() {  
// 向addListener()方法中传入适配器对象AnimatorListenerAdapter()
// 由于AnimatorListenerAdapter中已经实现好每个接口
// 所以这里不实现全部方法也不会报错
    @Override  
    public void onAnimationStart(Animator animation) {  
    // 如想只想监听动画开始时刻,就只需要单独重写该方法就可以
    }  
});

1.3 属性动画与补间动画的区别
应用对象不同,本质不同,适用范围有包含关系。

  • 补间动画的应用对象只能是View,不能用于非View对象,属性动画支持任意对象;
  • 补间动画的本质是对View做Transformation,并不能影响View的布局位置,只能影响View的可视位置。如果View从屏幕左边移动到右边,则其展示在右边了,但是这时候View相应点击事件还是在左边的位置,因为View并没有真的移动到右边,只是被绘制到右边了;
  • 及时动画对象是View,补间动画能做的也比较有限,只能做平移/旋转/缩放/透明度四种变化效果,假如我们要不断改变View背景色,就搞不定了,属性动画表示毫无压力;
  • 属性动画比补间动画更灵活,可以同时支持多个属性的动画,每个属性都可以独立定义插值器,各动画之间还可以做动画同步控制。
属性动画有关类的继承关系

1.4 Interpolator vs evaluator

  • Interpolator: 插值器, 用来定义animator变化的速率 (加速、减速...)
系统带的一些插值器.png

AccelerateDecelerateInterpolator 在动画开始与结束的地方速率改变比较慢,在中间的时候加速
AccelerateInterpolator 在动画开始的地方速率改变比较慢,然后开始加速
AnticipateInterpolator 开始的时候向后然后向前甩
AnticipateOvershootInterpolator 开始的时候向后然后向前甩一定值后返回最后的值
BounceInterpolator 动画结束的时候弹起
CycleInterpolator 动画循环播放特定的次数,速率改变沿着正弦曲线
DecelerateInterpolator 在动画开始的时候快然后慢
LinearInterpolator 以常量速率改变
OvershootInterpolator 向前甩一定值后再回到原来位置

  • evaluator: 返回动画在当前时间点所需要的值
    我们可以把动画的过程想象成是一部电影的播放,电影的播放中有进度条,Interpolator就是用来控制电影播放频率,也就是快进快退要多少倍速。然后Evaluator根据Interpolator提供的值(fraction)计算当前播放电影中的哪一个画面,也就是进度条要处于什么位置。

1.5 动画的过程中所涉及的计算

  • ValueAnimator对象会根据动画的总时间和已经流逝的时间计算出一个0到1之间的elapsed fraction值。这个elapsed fraction值就代表了时间完成的程度

  • 计算出elapsed fraction之后,ValueAnimator对象会调用TimeInterpolator
    来计算一个interpolated fraction,即,根据所设置的时间插值方法将elapsed fraction映射到interpolated fraction。 interpolated fraction 可能大于、小于、等于elapsed fraction,就看使用的什么插值器了。

  • interpolated fraction计算出来后,ValueAnimator 会调用TypeEvaluator,来进行你要动画的属性值的计算。
    这时候用的输入参数就是interpolated fraction的值,以及属性值的起始值和终止值。

动画计算流程图.png

ValueAnimator

  • 构造
    ValueAnimator.ofArgb
    ValueAnimator.ofInt
    ValueAnimator.ofFloat
    ValueAnimator.ofObject
    ValueAnimator.ofPropertyValuesHolder
ValueAnimator animator = ValueAnimator.ofInt(0, 400);
 animator.setDuration(1000);
  animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                int curValue = (int) animation.getAnimatedValue();
                tv.layout(curValue, curValue, curValue + tv.getWidth(), curValue + tv.getHeight());
            }
        });
 animator.start();

PropertyValuesHolder

  1. 保存了动画过程中所需要操作的属性和对应的值。
  2. 我们通过 ofInt(Object target, String propertyName, int… values)构造的动画,ofInt()的内部实现其实就是将传进来的参数封装成 PropertyValuesHolder 实例来保存动画状态。
  3. 在封装成 PropertyValuesHolder 实例以后,后期的各种操作也是以 PropertyValuesHolder 为主的。

自定义ValueAnimator

ObjectAnimator

ValueAnimator 有个缺点,就是只能对数值对动画计算。想对哪个控件操作,需要监听动画过程,在监听中对控件操作。
为了能让动画直接与对应控件相关联,以使我们从监听动画过程中解放出来在 ValueAnimator 的基础上,又派生了一个类 ObjectAnimator;
先看看利用 ObjectAnimator 重写的 ofFloat 方法如何实现一个动画:(改变透明度)

ObjectAnimator animator = ObjectAnimator.ofFloat(tv,"alpha",1,0,1);  
animator.setDuration(2000);  
animator.start(); 
  1. 要使用 ObjectAnimator 来构造对画,要操作的控件中,必须存在对应的属性的 set 方法
  2. setter 方法的命名必须以骆驼拼写法命名,即 set 后每个单词首字母大写,其余字母小写,即类似于 setPropertyName 所对应的属性为 propertyName ;
    set 函数调用频率是多少:动画在进行时,每隔十几毫秒会刷新一次,所以我们的 set 函数也会每隔十几毫秒会被调用一次。
    系统会根据属性通过反射找到对应属性的设置方法,刷新其值
  3. 何时需要实现对应属性的 get 函数。构造方法中最后一个参数都是可变长参数,从哪个值变到哪个值的,如果值传入了一个值,那默认值最终值,起始值就从get属性获取。

**自定义ObjectAnimator **

AnimatorSet

  • AnimatorSet 针对 ValueAnimator 和 ObjectAnimator 都是适用的;
  • playSequentially 表示所有动画依次播放,playTogether 表示所有动画一起开始。
  • setTarget属性,在 AnimatorSet 中设置以后,会覆盖单个 ObjectAnimator 中的设置;即如果 AnimatorSet 中没有设置,那么就以 ObjectAnimator 中的设置为准。

自定义Interpolator

public class AccelerateDecelerateInterpolator extends BaseInterpolator
        implements NativeInterpolatorFactory {
    public AccelerateDecelerateInterpolator() {
    }

    @SuppressWarnings({"UnusedDeclaration"})
    public AccelerateDecelerateInterpolator(Context context, AttributeSet attrs) {
    }

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

    /** @hide */
    @Override
    public long createNativeInterpolator() {
        return NativeInterpolatorFactoryHelper.createAccelerateDecelerateInterpolator();
    }
}

换成数学表达式

{0.5*cos[(input + 1)π] + 0.5}
余弦函数.png

在0-1之间,增长速度是先变快,后匀速,最后慢慢变慢

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

推荐阅读更多精彩内容