OverView
The property animation system is a robust framework that allows you to animate almost anything. You can define an animation to change any object property over time, regardless of whether it draws to the screen or not. A property animation changes a property's (a field in an object) value over a specified length of time. To animate something, you specify the object property that you want to animate, such as an object's position on the screen, how long you want to animate it for, and what values you want to animate between.
之前我们讲过View Animation他是只针对View来进行设置和实现动画效果的,而Property Animator可以针对任意对象的指定属性值进行修改,You can define an animation to change any object property over time。所以Property Animator要比View Animation强大的多,可以实现一些View Animation实现不了的效果。而且与View Animation不同的事,PropertyAnimator是会真实修改Object的属性值的,还是以View Animation中的例子来举例:将一个Button通过PropertyAnimator移动的新的位置之后,他的点击事件将会在新的位置被触发,说明button的真实位置已经被修改。
工作原理
讲解原理之前我们先明确几个Property Animator会用的属性,这些属性基本都在View Animation中使用过了,简单列一下不再详细说明:
duration:动画执行时长
interpolation:差值器
repeat count and model:动画重复执行次数和模式
Animator Set:属性动画的集合,可以设置一组属性动画
frame refresh delay:帧刷新间隔,默认10 ms刷新一次,但是也跟硬件性能和当然系统状态有关。官方文档说的是You can specify how often to refresh frames of your animation.但是并未提供接口来设置此属性。可能说的是startDelay?
以官方说明图解为例,来说一下Property Animator的工作原理:
动画的执行时长设置为40 ms,对对象的X属性值进行处理,指定的startValue和endValue分别为0跟40,默认10 ms刷新一次。
图例已经很直观了,10ms刷新一次一共有5帧动画对应的x值分别为0、10、20、30和40。典型的线性函数和匀速直线运动,不过多解释了。
上图的匀速直线运动是因为使用的interpolator是LinearInterpolator,interpolator是用来定义了动画速度变化曲线的。简单来说Interpolator规定动画什么时候该加速变化什么时候该减速变化。
这个图明显不是匀速直线运动了,他使用的是non-linear interpolator,他定义了一个先加速后减速变化的一个动画效果。
关于interpolator和TypeEvaluator的原理简单来说就是:动画执行的每一帧都会计算一个当前帧时间与动画总时长的一个比值input,拿此值去interpolator中获取一个fraction表明动画执行进度的值(如fraction等于0表明当然动画应取值应该是动画起始位置,等于1则表明在结束位置,此值可以小于0或大于1),以LinearInterpolator为例会将输入的input原封不动的返回,所以他是一个匀速直线运动,然后再拿fraction去TypeEvaluator获取具体的动画数值,然后设置为object的具体属性的值。原理大概了解就行,后面我们会以代码为例详细说明。
实现
ObjectAnimator
ObjectAnimator是系统提供的用来给任意Object的指定属性(该属性必须有setter方法)实现动画效果的,实现方式也有xml与java code两种方式。
XML实现
在res下定义animator文件夹,新建xml文件,文件以和标签开头,当然也可以以和开头下面我们再说这两个内容。
android:ordering=["together" | "sequentially"]
android:duration="2000">
android:propertyName="string"
android:duration="int"
android:valueFrom="float | int | color"
android:valueTo="float | int | color"
android:startOffset="int"
android:repeatCount="int"
android:repeatMode=["repeat" | "reverse"]
android:valueType=["intType" | "floatType"]/>
...
以translation为例具体实现如下:
android:duration="2000"
android:ordering="together">
android:propertyName="translationX"
android:valueFrom="0"
android:valueTo="200"
android:startOffset="0"
android:repeatCount="1"
android:repeatMode="reverse"
android:valueType="floatType"/>
android:propertyName="translation