Android动画原理分析
简单描述为:将View的一次大的属性变化拆分为多次小的属性变化,在每次VSYNC信号到来时,根据当前时间和插值器来计算当前View属性的值,然后给该View设置该属性值,直到动画执行完毕。其中Choreographer将动画拆分成一次次小的属性变化,Choreographer是动画的指挥者。理想情况下,属性刷新次数(动画拆分为多次小的属性变化)=动画执行时间/16.7ms。
我们从以下4个问题来讲解动画原理:
1:动画如何完成一次属性变化刷新?
点击按钮,开始执行透明度动画,直到动画结束。
下面就第一个问题进行源码分析,
首先从valueAnimator.start()开始:
1 设置相关标志位
2 这是个关键方法,动画循环中在该方法中实现。
3 初始化相关属性。
继续看核心方法:
由于ValueAnimator实现了AnimationHandler.AnimationFrameCallback接口。
1 动画开始执行时,mAnimationCallbacks.size是为0的,所以就会执行判断语句里面的方法getProvider().postFrameCallback(mFrameCallback);
2 将ValueAnmiator(实现了AnimationFrameCallback)添加入mAnimationCallbacks列表。
下面分析这句代码
是一个接口调用,下面我们看是谁实现了这个接口。
1 Choreographer收到VSYNC都会调用该方法,正常情况下16.7ms就会调用一次doframe。
2 再次将自己post到编舞者中,以便下次收到底层信号时,继续调用doFrame来刷新动画。
1 callback就是我们添加到mAnimationCallbacks列表中的ValueAnimator
2 执行ValueAnimator的doAnimationFrame方法;
1 在animateBaseOnTime中刷新View属性,并判断动画是否执行完毕
2 如果动画结束执行endAnimation。
1 首先将done布尔值为false,表示动画是否执行完毕,
2 这个值在ValueAnimator.startAnimator中将mRunning设置为true。
3 根据当前时间currentTime来判断动画是否执行完毕。
4 将dong值设置为true
5 计算当前View属性值,然后设置View相关属性。
下面继续看
1 getTarget返回的就是ValueAnimator valueAnimator = ObjectAnimator.ofFloat(mButton, "alpha", 1.0f, 0f);这句中的View也就是mButton。
2 调用父类,主要是计算当前动画的进度。
3 调用PropertyValueHolder.setAnimatorValue设置mButton在该帧的透明度
下面分析一下父类ValueAnimator的animateValue方法
1 根据插值器计算当前属性动画的进度。
2 android.animation.PropertyValuesHolder#calculateValue
将当前进度存放到PropertyValuesHolder.mAnimatedValue中,在AnimatorUpdateListener.onAnimationUpdate方法中可以通过ValueAnimator.getAnimatedValue获取动画进度。
3 回调AnimatorUpdateListener.onAnimationUpdate方法。
1 如果有属性,通过set方法来更新属性值。
2 如果需要通过反射来调用的setter方法来更新属性值。
以上流程就是完成了mButton透明度的一次更新,同时也说明了动画是如何完成一次属性变化的刷新。