基于滑动场景解析RecyclerView的回收复用机制原理

四级缓存

RecyclerView有mAttachedScrap->mCachedViews->ViewCacheExtension->RecycledViewPool四级缓存

mAttachedScrap:缓存屏幕内的ViewHolder,当RecyclerView需要重新layout时,会remove掉所有View,然后再add上去,那这暂时性的remove掉的View就存放在mAttachedScrap里;所以这个缓存主要用在layout时,屏幕内的ViewHolder不能用在滑动时复用,所以它和滑动缓存其实没什么关系

mCachedViews:缓存移出屏幕的ViewHolder,当position一致时才能被复用,复用时不调用onCreateViewHolder也不调用 onBindViewHolder

RecycledViewPool:在mCachedViews满了后,会把一个自己的ViewHolder存到RecycledViewPool,好空出位置来存放最新滑出屏幕的ViewHolder;RecycledViewPool每个type存储数量是5个,type一致就可以被复用,会调用onBindViewHolder重新绑定布局

mViewCacheExtension:这个是留给我们自己扩展的,好像也没怎么用

注:以下只讲一种ViewType的情况)

缓存

通过以上对四级缓存的说明,滑动缓存场景里主要用到的是mCacheViews和RecycledViewPool

mCacheViews最大缓存条数:

  默认缓存条数 = 2
  预缓存条数 = 一行;
  最大缓存条数 = 默认缓存条数 + 预缓存条数 

存入mCacheViews时机:

  • 当ViewHolder滑出屏幕外

  • RecyclerView会预加载一行,由于这一行一开始是不可见的,所以直接放进mCacheViews

mCacheViews超过最大缓存条数后,再有ViewHolder滑出屏幕,就会被放进RecycledViewPool;

复用滑动列表时,依次从mCachedViews->RecycledViewPool二级缓存里取出ViewHolder

屏幕里最多的View的数量?

RecyclerView的布局方式是根据滑动的方向,在滑出的一头删除,而在进入的另一头添加View,所以最多的View数就是一屏能容纳的最多Item数量;

最多创建几个ViewHolder?

如果缓存都没有命中就需要创建新的ViewHolder;考虑极端的情况,如果每次滑出的都是新的position时,mCachedViews缓存无法被复用,RecycledViewPool里如果也没有ViewHolder,那就需要不断创建新的ViewHolder,直到RecycledViewPool里有缓存为止;刚才说到mCachedViews满了之后,ViewHolder会被放进RecycledViewPool;

mCachedViews什么时候满?

mCachedViews达到最大缓存条数

mCachedViews满了时最多创建了多少ViewHolder?

ViewHolderCount = 第一屏数量 + 最大缓存条数 + 1(额外1个)

但忽略了一个问题是,如果一行有多列,每次都是一行一行地滑进滑出,缓存也是一行一行的存,那么需要达到的 最大缓存条数应该是列数的整数倍

Math.ceil(( ViewHolderCount + 1) / 列数) * 列数

经过实践,慢慢滑动时最多创建的ViewHolder数确实是ViewHolderCount,但快速滑动时就要创建列数整数倍个,猜测应该是快速滑动时来不及复用导致的

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值