RecyclerView中View的添加复用

RecyclerView源码解析
本文深入探讨RecyclerView的工作原理,包括view的添加与复用机制。详细分析了LayoutManager在滚动时如何判断添加子view,以及RecyclerView如何通过多级缓存实现view的高效复用。

本文以通俗的语言,记录在阅读RecyclerView源码时的一些心得🤔。

添加view的过程

  1. 在使用recyclerView的setAdapter方法设置adapter时,会调用RecyclerView的requestLayout()方法,进而执行measure、layout等生命方法;
  2. 何时添加的子view(adapter里面的一堆):在RecyclerView执行layout时,实际会调用LayoutManager的onLayoutChildren()方法去layout子view,如LinearLayoutManager,方法堆栈:onLayoutChildren()->fill()->layoutChunk()。
  3. 滚动时如何判断需要add一个子view:核心方法:updateLayoutState(),以向右滑动为例:①拿到当前最左边的view(getChildClosestToStart()),一般就是child0;②然后计算还可以向左滑动多远的距离才需要add一个view,getDecoratedStart()方法:计算最左边的子view在RecyclerView中的位置(getLeft()+margin)。经过计算之后可以知道:是否需要添加新的子view来填充RecyclerView。

View的复用

下面描述RecyclerView是如何对view进行复用的。
一、RecyclerView的缓存

  1. 一级缓存:mAttachedScrap
    mAttachedScrap中的view不需要重新bindView。ScrapView主要用于对于屏幕内可见的ChildView的缓存,缓存中的ViewHolder不需要重新Bind,缓存时机是在onLayout的过程中,并且用完即清空,里面的view只是被detach,不会被remove,在onLayout时会使用;
  2. 二级缓存:mCacheViews
    mCacheViews也不需要重新bind,里面的view是被remove过的,缓存滑动时即将离开RecyclerView的ViewHolder;
  3. 三级缓存:mViewCacheExtension
  4. 四级缓存:mRecyclerPool

二、view查找过程
在RecyclerView的view不足时,需要addView,view的查找过程如下,一层层降级获取可使用的view:

  1. 优先从mAttachedScrap列表中查找,查找的position必须和列表中某个holder的position完全一致,即:要查找的holder和该缓存里面的某个holder达到完全一致的状态;
  2. mCachedViews列表中查找,也需要position完全一致匹配。mCachedViews默认最大缓存为2,当大于该值时,将holder缓存移至RecycledViewPool;
  3. mAdapter.hasStableIds()为true时,否则转4:从mAttachedScrap、mCachedViews列表中查找viewType相同的holder,在1、2都失败的情况下,说明position完全匹配失败,这时候需要找到viewType相同的holder缓存;
  4. 从RecycledViewPool里面根据viewType查找缓存的holder。
    说明:RecycledViewPool针对每一种viewType有一个缓冲池,池子大小默认为5,当某一种viewType的holder在RecycledViewPool中的缓存数量大于最大值时,会被丢弃;
  5. 缓存全部无法命中,则调用Adapter.createViewHolder新建holder。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值