Android源码分析--动画框架AnimatorSet

我系苍王,多谢观看我这一个系列的课程,之前分析了Small插件化源码分析,近来看了Android里面的动画框架的相关代码,希望对感兴趣的同学一些帮助。


这一节,我要介绍的是AnimatorSet。

一提到android的动画,一定会涉及到AnimatorSet,因为他太好用了。它所封装的接口让很多复杂的动画叠加变得容易。

AnimatorSet是继承于Animator这个是非常重要的,因为AnimatorSet可以不停的叠加自身,最重要的是他本身就是一个Animator。

我们看一下他播放动画的方法,可以看到它返回的一个Builder的对象,可以推断它是使用建造者的形式,不断迭代动画。

Android源码分析--动画框架AnimatorSet_第1张图片

我们看一下他实际构造的时候使用,保存在mCurrentNode的Node对象里面,Node应该是节点的意思。

每个动画都应该由节点构成

Android源码分析--动画框架AnimatorSet_第2张图片

其Builder里面存在着三种排序,with,before,after(字面意思应该都很清晰)

(1)with的节点可以看到他是通过Dependency的方法来填充到mCurrentNode里面的,很明显with是并行的

Android源码分析--动画框架AnimatorSet_第3张图片

我们可以看到Dependency是只有WITH和AFTER两个时序。

Android源码分析--动画框架AnimatorSet_第4张图片

(2)当使用before的时候,相对于mCurrentNode是node节点之后,所以传入mCurrentNode到里面

Android源码分析--动画框架AnimatorSet_第5张图片

(3)当使用after的时候,相当于node节点是mCurrent节点之后,所以传入node到里面

Android源码分析--动画框架AnimatorSet_第6张图片

使用after延时,其实只是使用一个虚设一个ValueANimator来设定延时时间。

Android源码分析--动画框架AnimatorSet_第7张图片


然后我们看一下动画叠加真正的做法。

(1)playTogethor其实是使用with循环的叠加,其参数是不定量的数组的items

Android源码分析--动画框架AnimatorSet_第8张图片

   我们可以传入Collection的对象,意味着我们可以传入一个列表的Animator

Android源码分析--动画框架AnimatorSet_第9张图片

(2)playSequentially是不断使用before来将动画放在之后叠加

Android源码分析--动画框架AnimatorSet_第10张图片

setTarget的方法是循环获取node节点的animator动画,终节点通过ObjectAnimator来设置view目标

Android源码分析--动画框架AnimatorSet_第11张图片

setInterpolator设置时间插值器,这个插值器最后会在start的方法中是使用

Android源码分析--动画框架AnimatorSet_第12张图片

我们接下来看一下动画播放的流程

(1)start的方法会先设置一些标志位,然后通过遍历节点node的animator对象来设置播放同步为false

    遍历设置每个动画对象的运行时间

还会设置每个对象的时间插值器

Android源码分析--动画框架AnimatorSet_第13张图片

当使用play,playTogethor,playSequentially的时候还会标志需要排列节点,如果node节点没有依赖关系的话,全部会被排列到父节点里面,然后再次循环移除node的依赖父节点,加入到tmproot次节点之后,这样会建立一个统一的mSortedNodes的数组

Android源码分析--动画框架AnimatorSet_第14张图片

然后通过遍历mSortedNodes数组移除旧的监听器,

设置nodesToStart来控制全部的节点,

然后再次添加上对应的DependecyListener和AnimatorSetListerner

Android源码分析--动画框架AnimatorSet_第15张图片

如果判断延时少于0 ,就把节点的animator播放,并加到mPlayingSet里面,

否则添加值ValueAnimator作为延迟空效果,并通过监听器来在遍历播放节点

Android源码分析--动画框架AnimatorSet_第16张图片

通过通过回调来调用每个节点监听器的onAnimationStart,

如果判断节点内其全部的节点都被执行完,木有延迟,那么触发节点的onAnimationEnd的方法

Android源码分析--动画框架AnimatorSet_第17张图片

start的方法其实还需要涉及到DependecyListener

这里可以看明白,器通过调用onANimationStart和onAnimationEnd判断运行rule的规则来判断是否启动动画

Android源码分析--动画框架AnimatorSet_第18张图片

通过判断父AnimatorSet是否被取消返回

然后判断移除dependencies依赖关系

当全部依赖关系满足的时候,就开启动画

Android源码分析--动画框架AnimatorSet_第19张图片

(2)使用pause的方法,会让所有延迟的方法暂停,然后调用每个节点里的pause方法

Android源码分析--动画框架AnimatorSet_第20张图片

然后循环调用节点里面的onAnimationPause的方法,暂停每个动画。

Android源码分析--动画框架AnimatorSet_第21张图片

pause的方法是停止在中间的状态。

resume的方法也是类似的,用来恢复当前pause状态的动画运行

(3)canel的方法中,需要判断是否正在播放

如果正在播放会全部调用节点onAnimationCancel的方法,

然后再遍历调用延时动画的cancel方法和节点动画的cancel方法。

最后出发节点的onAnimationEnd的方法。

Android源码分析--动画框架AnimatorSet_第22张图片

触发剩余调用节点onAnimationCancel的方法,

Android源码分析--动画框架AnimatorSet_第23张图片

将全部动画监听器移除,将mPlayingSet的动画移除

将剩下的动画onDone状态设置为false,

触发节点的onAnimationEnd的回调方法

Android源码分析--动画框架AnimatorSet_第24张图片

cancel之后动画会停留在中间运行的状态

(4)另外一种end的方法也是可以停止动画运行,

可以看到会停止掉延迟,

然后调用每个动画的end方法和onAnimationEnd的方法,

最后设置回start的标志

Android源码分析--动画框架AnimatorSet_第25张图片

end和cancel的不同是,调用了end的方法,它会把动画直接发生整个动画的最后一帧然后停止。


关于AnimatorSet的源码分析就到这里了。

下一节内容敬请期待!!!

你可能感兴趣的:(Android源码分析--动画框架AnimatorSet)