学习Android动画过程,参考了众大神的文章自己消化(见参考资料)整理的一篇笔记,仅作个人备忘。
一、动画概况
Frame Animation:
帧动画,顺序播放事先做好的图像,是一种画面转换动画。图片过多、过大容易产生OOM。
类
对应xml标签
AnimationDrawable
逐帧动画(AnimationDrawable)
Tween Animation:
补间动画(又叫渐变动画),通过对场景里的对象不断做图像变换(平移translate、缩放scale、旋转rotate、透明度alpha)产生动画效果。
类
对应xml标签
Animation
AlphaAnimation
ScaleAnimation
TranslateAnimation
RotateAnimation
Animation类和其子类
Property Animation:
属性动画,通过动态地改变对象的属性从而达到动画效果,属性动画为API 11新特性。除了对View进行平移、缩放、旋转、透明度操作外,还可以将动画作用于指定的对象上。
类
对应xml标签
Animator
ObjectAnimator
ValueAnimator
Animator类及其子类
注意:
属性动画在3.0之后支持,之前的需要使用兼容库。
属性动画可以真正改变View的位置,而View动画则只在视觉上进行移动,实际位置并未改变。
属性动画属于Animator框架,补间动画属于Animation框架,帧动画属于Drawable框架。
二、概念理解
时间插值器
对于补间动画:时间插值器(TimeInterpolator)的作用是根据时间流逝的百分比计算出动画进度的百分比。根据百分比计算出动画开始的关键帧与将要显示的帧之间的差异(通过Transformation类的对象表示)。
对于属性动画:时间插值器(TimeInterpolator)的作用是根据时间流逝的百分比计算出动画进度的百分比(即属性值改变的百分比)。
常用的时间插值器对应的类与时间插值器(TimeInterpolator)之间的继承关系图
常用的时间插值器对应的类与时间插值器(TimeInterpolator)之间的继承关系图
类型估值器
类型估值器(TypeEvaluator)的作用是根据属性值改变的百分比计算出改变后的属性值(针对属性动画框架,View动画框架是不需要类型估值器的)。
属性动画实际上作用的是对象的属性,而属性的类型是不同的,因此Android内置了一些常用的类型估值器来操作不同类型的属性:
TypeEvaluator及其子类
动画工作原理
属性动画框架工作原理可以总结为如下三步:
在创建属性动画时如果没有设置属性的初始值,此时Android系统就会通过该属性的get方法获取初始值,所以在没有设置属性的初始值时,必须提供该属性的get方法,否者程序会Crash。
在动画播放的过程中,属性动画框架会利用时间流逝的百分比获取属性值改变的百分比(即通过时间插值器),接着利用获取的属性值改变的百分比获取改变后的属性值(即通过类型估值器)。
通过该属性的set方法将改变后的属性值设置到对象中。
只要某个类具有属性(即该类含有某个字段的set和get方法),那么属性动画框架就可以对该类的对象进行动画操作(其实就是通过反射技术来获取和执行属性的get,set方法),因此属性动画框架可以实现View动画框架的所有动画效果并且还能实现View动画框架无法实现的动画效果。
动画插值计算
属性动画最关键的部分就是值得计算,下图是计算的过程:
动画插值计算
计算过程分为三个阶段:
计算已完成分数。为了执行一个动画,你需要创建一个 ValueAnimator,并且指定目标对象属性的开始、结束值和持续时间。在调用 start 后的整个动画过程中, ValueAnimator 会根据已经完成的动画时间计算得到一个 0 到 1 之间的分数,代表该动画的已完成动画百分比。0 表示 0%,1 表示 100%。
计算插值(动画变化率)。 当 ValueAnimator 计算完已完成动画分数后,它会调用当前设置的 TimeInterpolator,去计算得到一个 interpolated(插值)分数,在计算过程中,已完成动画百分比会被加入到新的插值计算中。
计算属性值。当插值分数计算完成后,ValueAnimator 会根据插值分数调用合适的 TypeEvaluator 去计算运动中的属性值。
以上分析引入了两个概念:已完成分数(elapsed fraction)、插值分数( interpolated fraction )。
三、使用示例
Frame Animation:
xml方式实现
android:oneshot="true">//
java方式实现
view.setImageResource(R.drawable.icons);
AnimationDrawable animationDrawable = (AnimationDrawable) view.getDrawable();
animationDrawable.start();
Tween Animation:
xml方式实现
android:duration="2000"
android:fillAfter="true"
android:fromXDelta="0%"
android:fromYDelta="0%"
android:toXDelta="0%"
android:toYDelta="-100%" />
java方式实现
//View右移100像素
TranslateAnimation translateAnimation = new TranslateAnimation(0f, 0f, 0f, 100f);
translateAnimation.setDuration(2000);//动画的持续时间,单位毫秒
translateAnimation.setFillAfter(true);//参数为true表示动画结束后View停留在结束为止
view.startAnimation(translateAnimation);//开始动画
Property Animation:
xml方式实现
android:duration="2000"
android:valueFrom="0"
android:valueTo="50"
android:valueType="floatType" />
java方式实现
//View右移出屏幕再回来
float translationX = view.getTranslationX();
ObjectAnimator animator = ObjectAnimator.ofFloat(view, "translationX", translationX, 600f, translationX);
animator.setDuration(3000);
animator.start();
四、参考资料