RecyclerView缓存、复用

一、缓存

①布局缓存,mAttachedScrap 和 mChangedScrap,布局完成之后就会清空

RecyclerView 滑动场景来说,新卡位的复用以及旧卡位的回收, 不触发 mChangedScrap 和 mAttachedScrap

notifyItemChanged/rangeChange,此时如果Holder发生了改变,那就放入changeScrap,反之放入AttachScrap。

②mCachedViews

当列表滑动出了屏幕时,View已经从RecyclerView中detached或removed,ViewHolder会被缓存在 mCachedViews ,其大小由mViewCacheMax决定,默认DEFAULT_CACHE_SIZE为2,可通过Recyclerview.setItemViewCacheSize()动态设置。

存放的 ViewHolder 只有原本位置的卡位才能复用,不用重新绑定数据

③ViewCacheExtension

可以自己实现ViewCacheExtension类实现自定义缓存,通过Recyclerview.setViewCacheExtension()设置。

④RecycledViewPool

ViewHolder首先会缓存在 mCachedViews 中,当超过了个数(比如默认为2), 就会添加到 RecycledViewPool 中。RecycledViewPool 会根据不同ViewType把ViewHolder分别存储在不同的列表中,每个ViewType最多缓存DEFAULT_MAX_SCRAP = 5 个ViewHolder。

复用时,需要重新绑定数据。

二、滑动回收复用

滑动场景触发mCachedViews、RecycledViewPool缓存。

先复用再回收!!

①如下图,RecyclerView 向下滑动日志,第三行5个卡位的显示都是重新创建的 ViewHolder。

mCachedViews 优先级要高于 RecyclerViewPool,前者默认大小2,后者为5。所以,当第三行显示出来后,第一行的5个卡位被回收,先缓存在 mCachedViews,满了再移出到 ViewPool 里,所以5个卡位有2个缓存在 mCachedViews 里,3个缓存在 ViewPool。

至于是哪2个缓存在 mCachedViews,是由 LayoutManager 控制。这里例子使用的是 GridLayoutManager,滑动时的回收逻辑则是在父类 LinearLayoutManager 里实现,回收第一行卡位时是从后往前回收,所以最新的两个卡位是0、1,会放在 mCachedViews 里,而2、3、4的卡位则放在 ViewPool 里。

②所以,当再次向上滑动时,第一行5个卡位会去mCachedViews、RecycledViewPool里找复用,因为mCachedViews 里存放的 ViewHolder 只有原本位置的卡位才能复用,所以0、1两个卡位都可以直接去 mCachedViews 里拿 ViewHolder 复用,而且这里 ViewHolder 不用重新绑定数据。

至于2、3、4卡位则去 ViewPool 里找,刚好 ViewPool 里缓存着3个 ViewHolder,触发 onBindViewHolder() 方法,重新绑定数据,因此只有三个卡位需要重新绑定数据。

接着RecyclerView 向下滑动

RecyclerView 共创建17个 ViewHolder,是因为在第四行的卡位要显示出来时,ViewPool 里只有3个缓存,而第四行的卡位又用不了 mCachedViews 里的2个缓存(不是原本位置的卡位),所以就需要重新创建2个 ViewHodler 来给第四行最后的两个卡位使用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值