总结下
①RecyclerView
的复用机制就是当缓存中有ViewHolder
的时候,就直接用缓存(缓存分为四级)里面的,当没有的时候,就创建ViewHolder
,这时候会回调我们实现的onCreateViewHolder
和onBindViewHolder
方法。复用机制,有两个入口,分别是RecyclerView
的onTouchEvent
方法和RecyclerView
的onLayout
方法,到fill
方法的时候完成衔接。
②RecyclerView
的回收机制就是将ViewHolder
添加到缓存中的过程。有一个重要的方法,就是recyclerViewHolderInternal
,里面是二级缓存和四级缓存的元素添加,其中对于二级缓存,当元素数目多于某个值的时候,就会将ViewHolder
添加到四级缓存中,并且在添加之前会对ViewHolder
进行清空操作。一级缓存,四级缓存,就是将ViewHolder
直接添加进去,当然要对其进行清空之后。回收机制也是有两个入口,分别是LinearLayoutManager
的onLayoutChildren
,还有一个是fill
方法
一.一个问题
回收什么?复用什么?
都是ViewHolder
。它是对ItemView
的封装,可以理解成就是ItemView
。
二.复用机制
我们研究的问题,就是你使用RecyclerView
,滑动屏幕的时候,那些移出屏幕的ViewHolder
是怎么被回收的,那些刚进来屏幕的ViewHolder
是怎么被复用的。
研究复用,我们最开始想到的研究入口是去RecyclerView
的onTouchEvent
方法,因为滑动屏幕的时候应该会触发回收复用机制。
a.复用的第一个入口
(1)有缓存的时候
1.在onTouchEvent
中,我们看到MOVE
事件
2.然后往下找,找到scrollByInternal
3.然后追踪进入,找到scrollStep
,追踪进入
它这里就是根据不同方向分别做处理,思路都是一样的,所以我们看垂直方向的,也就是
4.追踪进入scrollVerticallyBy
由于它是调用的mLayout
的scrollVerticallyBy
,所以我们直接看LinearLayoutManager
的scrollVerticallyBy
方法(有人可能会有疑问,mLayout
明明是LayoutManager
类型的,但是为什么看LinearLayoutManager
呢?我认为是后面对mLayout
进行了赋值,将它赋值为LinearLayoutManager
类型的了)
5.发现它调用了scrollBy
,追踪进入,找到方法:fill
fill
即填充RecyclerView
的方法
6.在fill
里面,有layoutChunk
方法,它是循环调用的。我们追踪进入
可以看到它先得到view
,然后addView
这样就完成了,将view
从缓存中拿到以后填充到布局里面。那么具体是怎么拿的呢?
7.我们先看layoutState.next
。追踪next
8.找到getViewForPosition
方法,追踪
可以看到调用了tryGetViewHolderForPositionByDeadline
方法,我们所有复用的ViewHolder
返回,都是在这里面,也就是说它的作用就是将ViewHolder
从缓存里面拿出来。所以它非常重要。那么具体从哪拿呢?我们看下面
- 1.
mChangeScrap
与mAttachedScrap
:用来缓存还在屏幕内的ViewHolder
- 2.
mCachedViews
:用来缓存移除屏幕之外的ViewHolder
- 3.
mViewCacheExtension
:开发给用户的自定义扩展缓存,需要用户自己 管理View
的创建和缓存 - 4.
RecycledViewPool
:ViewHo