动画的分类
1.帧动画
2.补间动画
3.属性动画
帧动画:
继承结构:
–drawable
–DrawableContainer
–AnimationDrawable
可见:AnimationDrawable是继承的drawable。
用法:
- 在drawable目录下定义一个XML动画文件,根节点为animation-list,中间节点为item(item设置好图片和播放时间)
- 设置需要播放图片动画的ImageView的src属性。
- 代码中通过ImageView.getDrawable方法,获取到drawable,并强转成AnimationDrawable。
- AnimationDrawable.start()启动动画。
原理:
AnimationDrawable中保存有多张图片信息,按照顺序依次显示图片。
- start方法中,调用了setFrame方法
- setFrame,通过index得到图片信息,调用selectDrawable隐藏之前显示的图片,并调用Drawable的Callback重新绘制当前选中的图片。
- setFrame中接着调用scheduleSelf,执行run方法,run方法中执行了nextFrame,依次逐帧播放每一张图片。
补间动画
继承结构:
–Animation
–AnimationSet
–RotateAnimation
–ScaleAnimtation
–AlphaAnimation
–TranslateAnimation
XML文件对应
RotateAnimation–> rotate
ScaleAnimation–>scale
AlphaAnimation–>alpha
TranslateAnimation–>translate
属性说明:50:50px 50%相对自己的左上角 50%p父容器左上角
用法:
- 从xml读取动画文件。
对于AnimationSet,则
- 直接通过构造方法创建。
具体查看源码构造方法。
原理:
- View.startAnimation();保存了Animation,并请求父容器进行重新绘制。
- ViewGroup的draw方法中调用dispatchDraw()。
- dispatchDraw先处理LayoutAnimationController,即子控件的进出动画;再处理子控件的绘制,调用的是drawChild方法。
- drawChild。每个动画都重载了Animation的applyTransformation方法,通过getTransformation可以获取到当前时间点的Transformation对象(封装了matrix和alpha),然后canvas应用这个变换矩阵和alpha,最后再进行绘制图像。
属性动画
继承结构:
–Animator
–AnimatorSet
–ValueAnimator
–ObjectAnimator
–TimeAnimator
AnimatiorSet
用法
Animatorset s = new AnimatorSet();
s.play(anim1).with(anim2)
s.play(anim2).after(anim3)
s.start()
原理
AnimatorSet包括以下几个类:
- Node:记录当前动画和当前动画的关系集合。
- Depdency:记录一个Node和关系(with,after)
- Builder:管理Animator之间的关系。Builder.with,after,before来设置关系。
start()
- Duration>0,为所有的动画设置统一的duration。
- interpolator!=null,为所有动画设置统一的interpolator。 对动画Node节点进行排序。
- 先找出没有依赖其他的节点,组成roots
- roots中找出被其他依赖的节点。(with,after,before都会调用addDepdency方法会在节点中添加依赖,并且在两个节点上互相添加节点记录)
- 根据依赖关系为动画添加监听事件。 启动没有依赖关系的节点动画,监听事件中会依次启动其他依赖动画。
ValueAnimator
用法:
- 插值器:插值器是用来计算当前已经过的时间和属性值的改变比
- 估值器:通过属性值的改变比例估算当前属性值。
- 监听器:监听动画的改变
- 常用的方法(getAnimatedValue、getAnimatedFraction、其他一些set方法)
原理:
- 先使用PropertyValueHolder保存属性值。
- 设置好duration,interpolator,evaluator
- 调用start()方法开始执行动画
- start()中调用了animationHandler执行doAnimationFrame
- doAnimatorFrame调用了animatorFrame,最后调用了animtionValue方法
- animationValue先调用插值器的getInterpolation,获取当前的时间过去比例;再根据PropertyValueHolder.calculateValue计算当前的属性值。
- calculateValue中,调用了KeyFrameSet的getValue方法,这个方法会根据之前设置的Evaluator来进行估值,PropertyValueHolder保存估算的值,通过getAnimatedValue获取到。
重点
- 插值器
- 估值器