1.RecyclerView回收复用的谁?
2.RecyclerView有几级缓存?
3.如何实现自定义LayoutManager?
回收什么?复用什么?
回收到哪里去?从哪里获得复用?
什么时候回收?什么时候复用?
1.mChangeScrap与 mAttachedScrap
用来缓存还在屏幕内的 ViewHolder
2.mCachedViews
用来缓存移除屏幕之外的 ViewHolder
3.mViewCacheExtension
开发给用户的自定义扩展缓存,需要用户自己 管理 View 的创建和缓存
4.RecycledViewPool
ViewHolder 缓存池
所谓回收,就是看RecyclerView是怎么往四级缓存中添加数据的
mAttachedScrap 和 mChangedScrap
mCachedViews
ViewCacheExtension
这个的创建和缓存完全由开发者自己控制,系统未往这里添加数据
RecycledViewPool
notify
集合:
复用:从集合中去获取
入口:滑动 Move 事件 --> scrollByInternal --> scrollStep --> mLayout.scrollVerticallyBy
–> scrollBy --> fill --> layoutChunk --> layoutState.next --> addView(view);
layoutState.next --> getViewForPosition --> tryGetViewHolderForPositionByDeadline -->
怎么从集合中去获取:tryGetViewHolderForPositionByDeadline,分几种情况去获取ViewHolder
RecycledViewPool – 缓存池
ViewHolder – 包装View的 — ItemView
当没有缓存的时候??— mAdapter.createViewHolder --》 onCreateViewHolder
多级缓存的目的 – 为了性能
创建ViewHolder 后 绑定: tryBindViewHolderByDeadline–》 mAdapter.bindViewHolder–》onBindViewHolder
回收(缓存)机制:看这一个情况— 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);
mCachedViews当前的大小 如果 大于等于mViewCacheMax(默认的CachedViews的大小)
ViewType –
缓存池 里面保存 只是 ViewHolder 类型 没有数据
去查找缓存和复用的一种情况
入口:复用:RecyclerView.onLayout --> dispatchLayout --》 dispatchLayoutStep2 --》 onLayoutChildren --》 fill
缓存:fill -->recycleByLayoutState–>recycleViewsFromStart --> recycleChildren
–> removeAndRecycleViewAt --> recycler.recycleView
–> recycler.recycleViewHolderInternal(viewHolder); – 处理 CacheView 、RecyclerViewPool 的缓存
要学会copy系统的代码 — 怎么优化
layoutChunk --> layoutDecoratedWithMargins
notifyDataSetChanged–>mObservable.notifyChanged
–> (RecyclerViewDataObserver)mObservers.get(i).onChanged --> requestLayout
布局没变化