相对于View动画,属性动画有很多好处,比如:可以对任何对象操作,解决动画后控件点击区域问题等等。
我们以平移一个View展开来说:
文章图片
调用ObjectAnimator.ofFloat
时:
文章图片
创建了一个ObjectAnimator
对象,然后将传入的属性值保存下来,我们先看下anim.setFloatValues(values)
里面具体干了什么
文章图片
PropertyValuesHolder.ofFloat
里面会创建一个FloatPropertyValuesHolder
文章图片
文章图片
看它的成员变量命名,不难猜到,就是利用PropertyValuesHolder
来修改传入对象的属性的,具体实现是通过反射机制,通过拼接传入的属性名来反射到对应属性的set/get
方法,感兴趣的可以看下完整代码,这里就不阐述了,以免脱离主线,陷入源码无法自拔。
然后我们接着看ValueAnimator.setValues
文章图片
将PropertyValuesHolder
存到HashMap中,key为propertyName
, 以便取出对应属性的PropertyValuesHolder
然后我们返回来看下ObjectAnimator构造方法里面干了什么
文章图片
就是初始化了操作对象,操作对象的属性名
【Android|极简源码之Android ObjectAnimator实现原理】到现在为止,ObjectAnimator
的准备工作都做好了,然后就是调用start
方法开始执行动画了
文章图片
AnimationHandler
这个类的作用我们稍后揭晓,我们先看下父类,也就是ValueAnimator的start
实现
文章图片
文章图片
首先会检测下执行start
的线程是否属于Looper
线程(这也暗示了,是消息循环来驱动更新属性值,从而产生动画效果的),然后就是一堆变量的初始化,随后,会调用addAnimationCallback
文章图片
文章图片
,再次看到了AnimationHandler
,这个类是干什么用的呢?看类名,貌似是动画的处理者,我们看下类的实现
文章图片
有个static
的ThreadLocal
,负责存放对应Looper线程
的AnimationHandler
,以便对应线程获取
文章图片
文章图片
会维护一个Choreographer对象,看Choreographer类的实现,可以发现Looper,Handler,Message的痕迹,也验证了上文的推测:消息循环来驱动更新属性值。具体的实现这里就不阐述了。
AnimationHandler的作用大致就是:建立与Choreographer的联系,从而接收到系统的帧绘制消息,然后转发回ValueAnimator,然后再通过PropertyValueHolder给对象设置新属性值,然后产生动画效果。
驱动更新的位置找到了,那在什么位置更新对象的属性呢?
文章图片
文章图片
我们可以看到,计算当前时间点属性值的任务也是PropertyValuesHolder完成的, ValueAnimator.animateValue负责调用计算当前属性值方法,然后ObjectAnimator自动将新属性值设置给当前对象。
若有错误,欢迎指正!