阅读RecycleView源码的一些理解

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 的缓存

上一篇:【pyecharts数据可视化】python爬取去哪儿网景点数据,做交互式数据可视化


下一篇:django使用pyecharts(4)----django加入echarts_增量更新