RecyclerView相关属性
禁用滑动事件 : android:nestedScrollingEnabled="false"
设置滑动到边缘时无效果模式: android:overScrollMode="never"
设置不显示滚动条: android:scrollbars="none"
四级缓存
复用:从集合中去获取
入口:滑动 Move 事件 --> scrollByInternal --> scrollStep --> mLayout.scrollVerticallyBy --> scrollBy --> fill --> layoutChunk --> layoutState.next --> addView(view);
layoutState.next --> getViewForPosition --> tryGetViewHolderForPositionByDeadline -->
怎么从集合中去获取:tryGetViewHolderForPositionByDeadline,分几种情况去获取ViewHolder
-
getChangedScrapViewForPosition -- mChangeScrap 与动画相关
-
getScrapOrHiddenOrCachedHolderForPosition -- mAttachedScrap 、mCachedViews
-
getScrapOrCachedViewForId -- mAttachedScrap 、mCachedViews (ViewType,itemid)
-
mViewCacheExtension.getViewForPositionAndType -- 自定义缓存 -- (使用情况:局部刷新??)
-
getRecycledViewPool().getRecycledView -- 从缓冲池里面获取
RecycledViewPool -- 缓存池
ViewHolder -- 包装View的 --- ItemView
当没有缓存的时候??--- mAdapter.createViewHolder --》 onCreateViewHolder
多级缓存的目的 -- 为了性能
创建ViewHolder 后 绑定: tryBindViewHolderByDeadline--》 mAdapter.bindViewHolder--》onBindViewHolder
回收(缓存)机制:看这一个情况--- ViewHolder
LinearLayoutManager.onLayoutChildren --> detachAndScrapAttachedViews --> scrapOrRecycleView
--> 1.recycler.recycleViewHolderInternal(viewHolder); -- 处理 CacheView 、RecyclerViewPool 的缓存
- ViewHodler改变 不会进来 -- 先判断mCachedViews的大小
- mCachedViews.size 大于默认大小 --- recycleCachedViewAt --- >addViewHolderToRecycledViewPool --- 缓存池里面的数据都是从mCachedViews里面出来的
- 2.addViewHolderToRecycledViewPool --> getRecycledViewPool().putRecycledView(holder);
- scrap.resetInternal(); ViewHolder 清空
--> 2.recycler.scrapView(view);
缓存池 里面保存 只是 ViewHolder 类型 没有数据
public static class RecycledViewPool {
........
@Nullable
public ViewHolder getRecycledView(int viewType) {
final ScrapData scrapData = mScrap.get(viewType);
if (scrapData != null && !scrapData.mScrapHeap.isEmpty()) {
final ArrayList<ViewHolder> scrapHeap = scrapData.mScrapHeap;
for (int i = scrapHeap.size() - 1; i >= 0; i--) {
if (!scrapHeap.get(i).isAttachedToTransitionOverlay()) {
return scrapHeap.remove(i);
}
}
}
return null;
}
}
去查找缓存和复用的一种情况
入口:复用:RecyclerView.onLayout --> dispatchLayout --》 dispatchLayoutStep2 --》 onLayoutChildren --》 fill
缓存:fill -->recycleByLayoutState-->recycleViewsFromStart --> recycleChildren --> removeAndRecycleViewAt --> recycler.recycleView --> recycler.recycleViewHolderInternal(viewHolder); -- 处理 CacheView 、RecyclerViewPool 的缓存
RecyclerView与ListView的对比
RecyclerView和ListView都是用于加载大量数据的控件,RecyclerView作为listview的改进加强型,相对于ListView,RecyclerView做出了以下布局效果、局部刷新、动画效果、缓存知识优化:
1.布局效果
2.item点击事件
3.局部刷新
4.动画效果
5.缓存区别
是否需要回调createView | 是否需要回调bindView | 生命周期 | 备注 | |
mActiveViews | 否 | 否 | onLayout函数周期内 | 用于屏幕 itemView快 速重用 |
mScrapViews | 否 | 是 | 与mAdapter一致,当mAdatper被 更换时,mScrapViews即被清空 |
是否需要回调createView | 是否需要回调bindView | 生命周期 | 备注 | |
mAttachedScrap | 否 | 否 | onLayout函数周期内 | 用于屏幕内itemview快速重用 |
mCacheViews | 否 | 否 | 与mAdapter一致,当mAdapter被更换 时,mCacheViews即被缓存至 mRecyclerPool | 默认上限为2,即缓存屏幕外2 个itemView |
mViewCacheExtension | 不直接使用,需要用户在定制,默认不实现 | |||
mRecyclerPool | 否 | 是 | 与自身生命周期一致,不再被引用是即 被释放 | 默认上限为5,技术上可以实 现所有RecyclerViewPool共用 同一个 |