Recycler缓存机制
来源:互联网 发布:ubuntu如何更新软件源 编辑:程序博客网 时间:2024/06/06 10:34
首先来看RecycledViewPool
这是一个静态内部类,内部变量:
private SparseArray<ArrayList<ViewHolder>> mScrap = new SparseArray<ArrayList<ViewHolder>>();private SparseIntArray mMaxScrap = new SparseIntArray();
mScrap存放的是,每一个viewType对应的缓存viewHolder们,这些viewHolder装在arrayList中
mMaxScrap,每一个viewType对应着最多缓存多少个viewHolder的数量
put和get操作也比较简单
put: 找到viewType对应的arrayList,没有则new一个; 如果达到了最大直,那就不放了,
get:根据viewType找到对应的arrayList,没有就返回null
现在来看Recycler内部类,先看回收view,进入recycleView(View view)方法
开头那些判断先不管,直接进recycleViewHolderInternal方法
重要代码就这段, holder就是view的viewHolder
if (!holder.hasAnyOfTheFlags(ViewHolder.FLAG_INVALID | ViewHolder.FLAG_REMOVED | ViewHolder.FLAG_UPDATE)) { Log.d("xyz", "holder have no flags"); // Retire oldest cached view int cachedViewSize = mCachedViews.size(); if (cachedViewSize >= mViewCacheMax && cachedViewSize > 0) { Log.d("xyz", "recycle Cached view at 0"); recycleCachedViewAt(0); cachedViewSize --; } if (cachedViewSize < mViewCacheMax) { MyRecyclerAdapter.MyViewHolder myViewHolder = (MyRecyclerAdapter.MyViewHolder) holder; Log.d("xyz", "holder add to cache id="+String.valueOf(myViewHolder.id)+ " position="+String.valueOf(myViewHolder.getAdapterPosition())); mCachedViews.add(holder); cached = true; } }
这个mCachedViews就是一个ArrayList,第一个判断意思是,如果list已经达到最大值,那就把第一个扔到RecycleViewPool,再加到list的最后一个。
第二个判断就是如果list没到最大值,那就加到list里面。正常来说,第二个判断都会执行。
这里其实是二级缓存,第一级是mCachedViews,第二级是RecycleViewPool。
对于recycleCachedViewAt(0)方法,点进去你会发现,它会调用adapter的onViewRecycled方法,而且如果你给Recycler设置了监听RecyclerListener,里面的onViewRecycled也会调用。
进入RecycleViewPool时还会把viewHolder内部的标志位重置。
回收view看完,现在来看获取view
会调用getViewForPosition(int position, boolean dryRun)
1 直接看到方法 getScrapViewForPosition(position, INVALID_TYPE, dryRun) (dryRun为false)
首先从mAttachedScrap开始找,再从隐藏的view找,最后从mCachedViews找。
mCachedViews上面讲过了,来看一下mAttachedScrap,这是个ArrayList。
还记得刚开始的时候,layoutManager的onLayoutChildren会调用2次,第二次调用时,会先调用Recycler的detachAndScrapAttachedViews方法,这个方法会把所有view从RecyclerView detach,再加入mAttachedScrap。
所以这个时候,从mAttachedScrap就能得到。
2 第一个方法得不到,就会尝试从mViewCacheExtension获取。这个是开发者自定义的。
3 还是得不到,就从RecycleViewPool里取
4 还是得不到,那就调用adapter去创建viewHolder
以上就是找viewHolder的过程,找完之后,还要判断要不要bind,主要通过viewHolder的状态位判断。
getViewForPosition就结束了
- Recycler缓存机制
- ListView之Recycler机制
- RecyclerView机制分析: Recycler
- RECYCLER
- Recycler
- 你可能不知道的ListView Recycler机制
- 缓存机制
- 缓存机制
- 缓存机制
- 缓存机制
- 缓存机制
- 缓存机制
- 缓存机制
- 缓存机制
- 缓存机制
- 缓存机制
- 缓存机制
- 【缓存】-浏览器缓存机制
- 顺序结构,选择结构,循环结构的概念,用法,实例
- I/O流
- height、clientHeight、scrollHeight、offsetHeight区别
- Intellij IDEA设置显示行号
- Vue.js中的图片引用路径的方式
- Recycler缓存机制
- 什么是软件测试?
- HDU 5692 Snacks【线段树+DFS】
- Kafka副本同步机制理解
- BZOJ2957 楼房重建(线段树+思路)
- 求两个数最大公约数的方法
- 欧几里德算法LCM
- 如何用一个鼠标控制多台电脑?
- 火车票改签退票规则,儿童票规则