public class RecyclerView extends ViewGroup implements ScrollingView, NestedScrollingChild2
Recycleview继承自ViewGroup,即一个自定义ViewGroup。
onMeasure()
onmeasure中三个布局方法
第一个, 1- 处理适配器更新 2- 决定应该运行哪个动画 3 - 保存有关当前视图的信息 4- 如有必要,运行预测布局并保存其信息
dispatchLayoutStep1()
第二个布局步骤,对最终状态的视图进行实际布局。
dispatchLayoutStep2()
布局的最后一步,保存关于动画视图的信息,触发动画并进行必要的清理
dispatchLayoutStep3()
RecycleView的四级缓存
1. mChangeScrap 和 mAttachedScarp 用来缓存屏幕内的ViewHolder
final ArrayList<ViewHolder> mAttachedScrap = new ArrayList<>(); ArrayList<ViewHolder> mChangedScrap = null;
2. mCachedViews 用来缓存移出屏幕外的ViewHolder,默认max=2
final ArrayList<ViewHolder> mCachedViews = new ArrayList<ViewHolder>();
3. mViewCacheExtension 自定义扩展缓存,需要开发者自己管理View的创建和缓存,一般用不到
4. RecycleViewPool ViewHolder缓存池,默认max=5,缓存池里只保存ViewHolder类型没有数据
public static class RecycledViewPool {
private static final int DEFAULT_MAX_SCRAP = 5;
static class ScrapData {
final ArrayList<ViewHolder> mScrapHeap = new ArrayList<>();
int mMaxScrap = DEFAULT_MAX_SCRAP;
long mCreateRunningAverageNs = 0;
long mBindRunningAverageNs = 0;
}
SparseArray<ScrapData> mScrap = new SparseArray<>();
}
当没有缓存的时候,执行mAdapter.createViewHolder --》 onCreateViewHolder
入口:滑动 Move 事件 --> scrollByInternal --> scrollStep --> mLayout.scrollVerticallyBy
--> scrollBy --> fill --> layoutChunk --> layoutState.next --> addView(view);
layoutState.next --> getViewForPosition --> tryGetViewHolderForPositionByDeadline
怎么从集合中去获取:tryGetViewHolderForPositionByDeadline,分几种情况去获取ViewHolder
1. getChangedScrapViewForPosition -- mChangeScrap 与动画相关
2. getScrapOrHiddenOrCachedHolderForPosition -- mAttachedScrap 、mCachedViews
3. getScrapOrCachedViewForId -- mAttachedScrap 、mCachedViews (ViewType,itemid)
4. mViewCacheExtension.getViewForPositionAndType -- 自定义缓存 -- (使用情况:局部刷新??)
5. getRecycledViewPool().getRecycledView -- 从缓冲池里面获取
回收(缓存)机制:看这一个情况--- ViewHolder
LinearLayoutManager.onLayoutChildren --> detachAndScrapAttachedViews --> scrapOrRecycleView
--> 1.recycler.recycleViewHolderInternal(viewHolder); -- 处理 CacheView 、RecyclerViewPool 的缓存
--> 1.ViewHodler改变 不会进来 -- 先判断mCachedViews的大小
--> mCachedViews.size 大于默认大小 --- recycleCachedViewAt
--- >addViewHolderToRecycledViewPool --- 缓存池里面的数据都是从mCachedViews里面出来的
--> 2.addViewHolderToRecycledViewPool --> getRecycledViewPool().putRecycledView(holder);
--> scrap.resetInternal(); ViewHolder 清空
--> 2.recycler.scrapView(view);
去查找缓存和复用的一种情况
入口:复用:RecyclerView.onLayout --> dispatchLayout --》 dispatchLayoutStep2 --》 onLayoutChildren --》 fill
缓存:fill -->recycleByLayoutState-->recycleViewsFromStart --> recycleChildren
--> removeAndRecycleViewAt --> recycler.recycleView
--> recycler.recycleViewHolderInternal(viewHolder); -- 处理 CacheView 、RecyclerViewPool 的缓存