LayoutManager mLayout;
mylayout实际上是LinearLayoutManager
recycleView的设计实际上就是在不同的场景下传入不同的实现类就可以实现不同的效果
final boolean canScrollHorizontally = mLayout.canScrollHorizontally();
final boolean canScrollVertically = mLayout.canScrollVertically();
复用流程
move动作里面
调用了scrollByInternal
scrollByInternal调用了scrollStep
scrollStep调用了scrollStep
scrollStep调用了LinearLayoutManager中的scrollHorizontallyBy/scrollVerticallyBy
实际上scrollHorizontallyBy和scrollVerticallyBy是一样的代码
![](https://i-blog.csdnimg.cn/blog_migrate/d7adb1fd283e79d5593beadba665f744.png)
![](https://i-blog.csdnimg.cn/blog_migrate/027d9e5036c553ae3dd023266d222968.png)
scrollBy是为了调用fill方法
fill里的方法主要做两件事,一个回收一个复用
![](https://i-blog.csdnimg.cn/blog_migrate/db307a5c5153b72f7f84b782d786e61b.png)
layoutChunk复用代码
while ((layoutState.mInfinite || remainingSpace > 0) && layoutState.hasMore(state)) {
循环添加view到RecycleView当中去
向上添加还是向下添加是前面代码定义的
RecycleView的添加VIew方式依旧是addView的方式添加
![](https://i-blog.csdnimg.cn/blog_migrate/e5e6e204d16863440d0e05c0745b82af.png)
![](https://i-blog.csdnimg.cn/blog_migrate/4d9926d0a19872a55327c3288554861d.png)
![](https://i-blog.csdnimg.cn/blog_migrate/3a64f975355d14fc0a31790b30bd74b3.png)
当viewHolder获取失败才会继续获取
tryget方法是RecycleView的四级缓存
四级缓存
1mChangeScarp与mAttachedSecrap
2mCachedViews
3mViewCacheExtension
4RecycledViewPool-
ListView只有两级缓存
mChangeScarp与mAttachedSecrap是与屏幕分离和未分离 detch缓存在这边
mCachedViewsmove 缓存在这边
mViewCacheExtension 自定义的复用机制
RecycledViewPool默认缓存 缓存池
mChangedScrap是一个复用的集合
复用的对象是ViewHolder
ViewHolder可以理解为View的容器
当前方法是用过position去查找
![](https://i-blog.csdnimg.cn/blog_migrate/c09b14c907992df8058ceb783c101235.png)
1/2级缓存是在方法中存储下来的
来源于onLayout和onMeanue工作当中
![](https://i-blog.csdnimg.cn/blog_migrate/1774764ecac782aaff4d65337a21f7be.png)
接下来会在
![](https://i-blog.csdnimg.cn/blog_migrate/ca27549b0cc12233a3cb7c62c110af50.png)
进行复用
接下来会在进行复用(二级缓存)
![](https://i-blog.csdnimg.cn/blog_migrate/a659d17554063586bba7e45cdceabc45.png)
上面的复用都是通过position来查找,而下一步,是通过id进行查找
同样的一级缓存
![](https://i-blog.csdnimg.cn/blog_migrate/83b286e3a8730488a66a2759e97fb2e4.png)
接下来的二级缓存
![](https://i-blog.csdnimg.cn/blog_migrate/c919c3f7a88046d8fb2c2a4c985acfa2.png)
当一二级缓存均无法获得(holder==null)如果holder有值就不会继续
![](https://i-blog.csdnimg.cn/blog_migrate/fdf1219766da02e9db16aece7e795b1b.png)
开始从我们自定义的缓存中获取参数
第四级就是pool
![](https://i-blog.csdnimg.cn/blog_migrate/3e294e17dd57fc738dc4e121bb7e268b.png)
首先获取我们的pool
![](https://i-blog.csdnimg.cn/blog_migrate/124d7cb179da58cc2d77c8afb7fdacf0.png)
viewType
SparseArray key是viewType value是ScrapData
ScrapData里存放的是ViewHodler的集合
![](https://i-blog.csdnimg.cn/blog_migrate/108cc52c40717acfe47813fda1432c4d.png)
Pool是一个栈结构
如果四级缓存都没拿到就使用create
![](https://i-blog.csdnimg.cn/blog_migrate/14d79a7cf2ee8bae27a8d557ca7dc822.png)
接下来将viewHolder存入池中
![](https://i-blog.csdnimg.cn/blog_migrate/24cfd7489dd70ac2671729e5daf1dfc6.png)
接下来是回收流程
![](https://i-blog.csdnimg.cn/blog_migrate/b206c8781493b4c9f1cdfb15788d1d0d.png)
先确定mCachedViews的大小
![](https://i-blog.csdnimg.cn/blog_migrate/2a521a55dcd670019ae230b5339779d8.png)
在cacheView是先进先出的数据结构,因为每次拿到的都是第0个
然后添加到了pool中
![](https://i-blog.csdnimg.cn/blog_migrate/c16d8ffed44d2bfe16df504b2f7c31b6.png)
然后添加到集合当中,然后判断尺寸是否大于max
![](https://i-blog.csdnimg.cn/blog_migrate/225edf050ff6f4db787976cd147d845b.png)
而大于一定数量就不会再添加到池了,就会不断create
![](https://i-blog.csdnimg.cn/blog_migrate/d8a0df9fceb92112fd31edab15ebb294.png)
首先先将
cacheView的第0个,第0个是最老的,将他移除,通过remove的方式获得添加进回收池pool,所谓的mScrap
![](https://i-blog.csdnimg.cn/blog_migrate/4ef93875ff5830e37c41fb651c5e6475.png)
顾名思义,废弃池
但是废弃池也是我们RecycleView的第四级缓存
onLayout的时候会将View添加到一二级缓存
![](https://i-blog.csdnimg.cn/blog_migrate/989f5d096ae5a77d2feba04f8088e0b1.png)
而显示错乱也在这里得到了解释,因为我们在复用ViewHodler
解决ViewHodler的错乱可以让绑定不同的参数
ViewType对应的缓存pool默认是5个
但是如果有三个viewtype就有15个
5n+2的关系