Recycler
作为RecyclerView的内部类,Recycler负责管理废弃或分离的项目视图以供重用。
以下摘自Recycler源码
final ArrayList<ViewHolder> mAttachedScrap = new ArrayList<>();
ArrayList<ViewHolder> mChangedScrap = null;
final ArrayList<ViewHolder> mCachedViews = new ArrayList<ViewHolder>();
private final List<ViewHolder>
mUnmodifiableAttachedScrap = Collections.unmodifiableList(mAttachedScrap);
private int mRequestedCacheMax = DEFAULT_CACHE_SIZE;
int mViewCacheMax = DEFAULT_CACHE_SIZE;
RecycledViewPool mRecyclerPool;
private ViewCacheExtension mViewCacheExtension;
static final int DEFAULT_CACHE_SIZE = 2;
复用
在滑动RecyclerView的过程中,当有新的item将要展示出来时,会先根据position从Recycler中的mCachedViews中取,如果获取不到,则再到mRecyclerPool中取。
因为是根据item位置获取的,从mCachedViews取出的viewholder还保持着数据,取到可直接显示。从mRecyclerPool取到的,会调用 resetInternal() 来重置 ViewHolder,所以会重新调用onBindViewHolder()来绑定数据。
回收
随着滑动完全滑出屏幕的item会被回收viewholder
当前被回收的ViewHolder会放入mCachedViews,mCacheViews的最大缓存大小由mViewCacheMax控制,默认值是2,当mCacheViews缓存数量已达最大值,会将第一个ViewHolder移动到mRecyclerPool中,再将需要缓存的ViewHolder加入到mCacheViews尾部。
RecyclerPool中的ViewHolder是根据viewType分类缓存的,默认每种最多存5个。
总结
RecyclerView 滑动场景下的回收复用涉及到的结构体两个:
ArrayList<ViewHolder> mCachedViews
和
RecycledViewPool mRecyclerPool
mCachedViews 优先级高于 mRecyclerPool,回收时,最新的 ViewHolder 都是往 mCachedViews 里放,如果它满了,那就移出一个扔到 mRecyclerPool里好空出位置来缓存最新的 ViewHolder。
复用时,也是先到 mCachedViews 里找 ViewHolder,但需要各种匹配条件,概括一下就是只有原来位置的卡位可以复用存在 mCachedViews 里的 ViewHolder,如果 mCachedViews 里没有,那么才去 mRecyclerPool里找。
在 mRecyclerPool里的 ViewHolder 都是跟全新的 ViewHolder 一样,只要 type 一样,有找到,就可以拿出来复用,重新绑定下数据即可。
如果既没有从mCacheViews中找到匹配position的,也没有从mRecyclerPool中找到viewType一致的ViewHolder,就只能调用 Adapter 的 onCreateViewHolder 来创建一个新的 ViewHolder 使用了。