概述
上一篇我们针对RecyclerView的绘制流程做了简单的分析,重点放在了dispatchLayoutStep2()这个真正对子View操作的函数上,它完成了:子View的添加(LinearLayoutManager通过ChildHelper添加)、测量、布局。
绘制流程虽然有了大概的了解,但却引出了很多问题:dispatchLayoutStep1()和dispatchLayoutStep3()有什么作用?ChildHelper如何管理子View?动画怎么产生?Recycler如何回收和提供ViewHolder?等等等等。
Recycler的问题这一篇依旧不讲(实在解耦得太好了以至于可以随时单独拿出来讲),我们下面着重来看一下数据变动下View的动画到底是如何产生的,顺带对上面的一些问题作出分析。
在网上看了好几篇博客都看得云里雾里,后来索性找到了参与编写RecyclerView的工程师写的解释RV动画的博客才梳理通了整个流程,大家可以直接去看原博客,我在跟源码的过程中会把对博客的理解写出来。
首先说明几个类。
AdapterHelper
这个类的介绍是Helper class that can enqueue and process adapter update operations,可以入列和执行adapter的更新操作,个人理解是AdapterHelper托管了Adapter的数据更新操作,即Adapter中Datas改变后调用的notifyItemXXX()都是由AdapterHelper来执行的,而且这个数据的变化到界面上的变化这之间是经历一个onLayout的,AdapterHelper将Adapter的操作记录为一个对象(UpdateOp),并且操作的结果映射在VH的position上,并通过onLayout的过程显示出来。重要的地方注释了, 还有很多方法没有列出来,到具体用到的时候再说。
class AdapterHelper implements OpReorderer.Callback { //一些数据结构保存UpdateOp private Pools.Pool<UpdateOp> mUpdateOpPool = new Pools.SimplePool<UpdateOp>(UpdateOp.POOL_SIZE); final ArrayList<UpdateOp> mPendingUpdates = new ArrayList<UpdateOp>(); final ArrayList<UpdateOp> mPostponedList = new ArrayList<UpdateOp>(); final Callback mCallback; Runnable mOnItemProcessedCallback; final boolean mDisableRecycler; //一个可以实现UpdateOp排序的类,似乎是因为对数据集的操作有优先级 final OpReorderer mOpReorderer; private int mExistingUpdateTypes = 0; AdapterHelper(Callback callback) { this(callback, false); } //在RecyclerView初始化的时候我们新建了一个AdapterHelper,并且传入了一个实现了这个Callback的匿名内部类作为AdapterHelper和RV通信手段 AdapterHelper(Callback callback, boolean disableRecycler) { mCallback = callback; mDisableRecycler = disableRecycler; mOpReorderer = new OpReorderer(this); } AdapterHelper addUpdateOp(UpdateOp... ops) { Collections.addAll(mPendingUpdates, ops); return this; } //封装各种操作 static class UpdateOp { static final int ADD = 1; static final int REMOVE = 1 << 1; static final int UPDATE = 1 << 2; static final int MOVE = 1 << 3; static final int POOL_SIZE = 30; int cmd; int positionStart; Object payload;