功能强大的动画系统——属性动画(一)

1.前言


通过上一讲的内容,可以知道补间动画能实现我们大部分的界面效果。但是,作为最早引入的动画系统,仍有一些令人不满意的地方。

  • 动画种类有限,只能是透明度、位移、旋转、缩放这几种动画效果及其组合。所能做的,就是通过Interpolator改变动画进行中的效果。
  • 动画效果仅仅是视图层面的,对控件的实际并没有影响。

而导致这些的原因,就是因为动画的操作对象是控件的行为,所以无法对控件本身做出改变。

2.属性动画


安卓后来推出属性动画的目的就是为了弥补补间动画的缺陷。因为它可以对控件的属性进行操作,默认支持float,int和六位十六进制颜色。若属性不在这个范围内,自己提供一个TypeEvaluator转换即可。而且,可以与补间动画共用系统提供的Interpolator,并通过Keyframe和AnimatorSet扩展对动画的控制。


property animation.png

3.具体使用


拿最具代表性的ObjectAnimator来说吧,只需调用实例的start()方法就可以启动动画,所以构建ObjectAnimator实例就是原生动画最核心的部分。系统提供了三种创建实例的方法:

  • 通过ObjectAnimator.ofXXX()的方法生成动画对象。
  • 新建ObjectAnimator对象,再通过setXXX()的方法添加所需参数。
  • 通过AnimatorInflater.loadAnimator(Context context, int id) 的方法加载XML的配置文件,生成动画对象。文件放在res/animator文件夹下,通过R.animator.XXX来引用。

我们先看看,ObjectAnimator的XML属性有哪些,以及代码中如何设置:

android:propertyName
必需,进行动画的属性的名称,对应控件中setXXX方法(驼峰命名)。映射时,默认只将属性名第一个字母大写,所以其它必须符合驼峰命名。
由于执行动画的控件不能在XML中设置,必须在代码中调用setTarget(Object target) 绑定。
代码表示:setPropertyName(String propertyName) 

android:valueTo
必需,动画结束时属性的值。
代码表示:setFloatValues(float... values) / setIntValues(int... values)

android:valueFrom
动画开始时属性的值。若没有指定,将从控件属性对应的get方法中获得。若还没有,则使用数据类型的默认值。
代码表示:setFloatValues(float... values) / setIntValues(int... values)

android:duration
动画执行的时间,毫秒为单位,默认300毫秒。
代码表示:setDuration(long duration) 

android:startOffset
start()方法调用后,动画延迟播放的时间,毫秒为单位。
代码表示:setStartDelay(long startDelay) ,父类的方法。

android:repeatCount 
定义动画被重复执行的次数。默认值是0,而-1(INFINITE)表示无限循环。
代码表示:setRepeatCount(int value) ,父类的方法。

android:repeatMode
当repeatCount>0或者=-1,且动画执行到了终值时,进行的重复行为的类型。
repeat(RESTART)是默认值,表示从头开始。reverse(REVERSE),表示反向开始。
代码表示:setRepeatMode(int value) ,父类的方法。

android:interpolator
插值器,与补间动画中的作用相同,可以共用。默认是AccelerateDecelerateInterpolator。
代码表示:setInterpolator(TimeInterpolator value) ,父类的方法。

android:valueType
关键字,若类型是颜色,不设置此属性。
floatType是默认值,表示为浮点型。intType,表示为整型。
代码表示:无相应的方法。

由这些属性我们可以发现propertyName决定了属性动画比补间动画要强大,夸张点说,View及其子类有多少set开头的方法,就有多少种动画。那么实现补间动画的效果对于属性动画而言不难:

// 透明度:alpha
void setAlpha(float alpha)

// 位移:translationX、translationY
void setTranslationX(float translationX) 
void setTranslationY(float translationY)

// 中心点:pivotX、pivotY
void setPivotX(float pivotX) 
void setPivotY(float pivotY) 

// 旋转:rotation、rotationX、rotationY
void setRotation(float rotation)
void setRotationX(float rotationX)
void setRotationY(float rotationY)

// 缩放:scaleX、scaleY
void setScaleX(float scaleX)
void setScaleY(float scaleY)

根据上面的属性可以很容易地用后两种方式写出动画,但是系统给我们提供了更简单的,也就是第一种方式。

// 第一个参数指定执行动画的控件对象。
// 第二个参数指定被动画操作的控件的属性名,与android:propertyName用法一致。
// 第三个是可变参数,指定动画值的改变轨迹。由于参数数量不定,变化更加灵活。
ObjectAnimator.ofFloat(Object target, String propertyName, float... values) 
ObjectAnimator.ofInt(Object target, String propertyName, int... values) 
// API 21为了支持alpha值引入的
ObjectAnimator.ofArgb(Object target, String propertyName, int... values) 

属性动画推荐用代码进行实现,因为使用XML配置就和补间动画一样只有开始值和结束值,变化过于单一,若通过Interpolator进行调整,需要自己设计轨迹表达式,比较麻烦,大部分人不会和自己过不去。
  与补间动画相比,仍有个问题没有解决,一个动画只能对一个属性进行改变,多个动画如何组合起来。肯定就是AnimatorSet,它特有的属性只有一个(与补间动画一样,对它设置的公共属性,有的是覆盖子动画的同名属性,有的对它自己起作用,有的直接忽略,不推荐使用):

android:ordering 
关键字,指定此集合中动画的播放顺序。
together是默认值,表示同一时间内播放动画。sequentially,表示按顺序进行播放动画,注意避免出现循环。
代码表示:
playTogether(Collection<Animator> items) 
playTogether(Animator... items) 
playSequentially(List<Animator> items) 
playSequentially(Animator... items) 

这种将动画一次性加入,设定播放顺序,让子动画根据自己的设置播放,显得不够精细,无法处理同时播放和顺序播放混合的动画。所以,添加了play(Animator anim) 方法,使用构造器模式,一个一个地添加动画,并设置播放关系。详细的方法如下图所示:


AnimatorSet.Builder.png

动画多了后,对于延迟的处理比较麻烦。延迟有个概念要理解,它指的是在动画的播放前加了等待时间,也就是说,被延迟的动画是非播放状态的。所以AnimatorSet的延迟对所有子动画起作用,毕竟动画都没被启动,而两个动画一起播放,是指一个动画启动另一个动画,启动的必然处于播放状态,被启动的可能处于延迟状态,切记。

4.内容解释


由于属性动画的功能比补间动画多了太多,既有相似的,又有完全新的概念,实在不知道按什么顺序写。这一讲是从补间动画过渡到属性动画,所以内容上尽量保持一致,毕竟比它强大的前提是能实现它。大家可以对比理解。

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

推荐阅读更多精彩内容

  • 1 背景 不能只分析源码呀,分析的同时也要整理归纳基础知识,刚好有人微博私信让全面说说Android的动画,所以今...
    未聞椛洺阅读 2,688评论 0 10
  • 在手机上去实现一些动画效果算是件比较炫酷的事情,因此Android系统在一开始的时候就给我们提供了两种实现动画效果...
    Ten_Minutes阅读 3,870评论 3 11
  • 写的非常好,强烈推荐给大家 转载请注明出处:http://blog.csdn.net/guolin_blog/ar...
    天天大保建阅读 773评论 0 1
  • 有一种责任,叫做不忍 有一种缘分,叫做宿命 人生是一场没有结辩的辩论,自己跟自己辩 不论是正方还是反方,你总有理由...
    简溪小书房阅读 166评论 0 0
  • goddessna阅读 218评论 0 0