RecycleView有几级缓存?
4级;RecycleView实现了3个,其中一个提供给程序员实现;
- 第一级:ArrayList<ViewHolder> mAttchedScrap;
- 第二级:ArrayList<ViewHolder> mCachedViews;
- 第三级:ViewCacheExtension mViewCacheExtension;是个抽象类,没有被实现,提供给用户用的,让用户去实现的;
- 第四级:RecycleViewPool mRecyclePool; 二维数组:SparseArray<ScrapData>; key为int类型的viewType,值为ScrapData对象; ScrapData里面有ArrayList<ViewHolder>,这个list数量默认最大5个;
SparseArray比HashMap高效;
它们的作用分别是什么?
作用 | 缓存数量 | 缓存类型 | |
mAttchedScrap | 1、缓存正在显示的Item 2、方面快速查找、删除 | n个:屏幕中显示的数量 | ViewHolder |
mCachedViews | 防止用户滑出去,又滑回来 | 2个:缓存2个刚滑出去的viewHolder,不清除数据 | ViewHolder |
mViewCacheExtension | 让用户去实现 | - | - |
mRecyclePool | 不用再重复inflate,提高性能 | n个:缓存从二级缓存中移除的Item,每个viewType对应的List<ViewHolder>数量是5; | 二维数组:SparseArray<ScrapData> |
第一屏的加载时间是最大的:因为需要inflate进行解析XML实例化为View;
之后会从缓存中取View;
刚加载第一屏时:
- 先去从二级缓存中找viewholder,肯定null
- 二级没有,则去四级缓存中找,也为空
- 四级没有,则去适配器创建,并绑定数据
- 往一级缓存中set显示的ViewHolder数据
滑动时要移除屏幕:
- 先将完全不可见item从一级缓存中移除
- 将这个完全不可见item的position和ViewHolder(ViewHolder对象里面有个mPosition,是记录这个ViewHolder的position)的放入二级缓存,不清空view里的数据
- 如果二级缓存中数据小于2个,则直接添加进二级缓存
- 如果二级缓存之前有数据且等于2个,则将二级缓存里的移除一个,放到四级缓存中
滑动时要添加时:
- 先从二级缓存中找viewholder,
- 判断要显示的position和这个viewholder的mPosition是否一样
- 一样则直接用二级缓存里的这个viewholder,不用重新绑数据
- 将viewholder添加进一级缓存
- 不一样则去四级缓存里根据viewtype拿viewholder
- 重新绑定数据
- 将viewholder添加进一级缓存
scrollBy:
注意:scrollBy只移动了画布Canvas,view的实际位置并没有改变;需要配合layout使用;
scrollBy(100,100):相对view当前位置,向左上移动各100像素;
scrollBy(-100,-100):相对view当前位置,向右下移动各100像素;
scrollTo:
scrollTo(100,100):直接移动到父容器(100,100)的位置;
scrollTo(-100,-100):直接移动到父容器(-100,-100)的位置;