学而不思则罔,思而不学则殆
相关文档:
RecyclerView学习(一)之应用
RecyclerView学习(二)之缓存探索
RecyclerView学习(三)之缓存原理分析
我们都知道RecyclerView有缓存有复用,但是缓存的现象是什么呢?
今天我们就来探索一下缓存复用的现象,然后通过现象去研究本质
//RecyclerView 版本
implementation 'androidx.recyclerview:recyclerview:1.1.0'
class StudyOneAdapter(list: List<Bean?>) : RecyclerView.Adapter<StudyOneAdapter.TestHolder>() {
private val sTAG = "zy.StudyOneAdapter"
private var mList: List<Bean?> = mutableListOf<Bean?>()
private var mCreateNum = 0
private val mHolderList = mutableSetOf<TestHolder>()
init {
mList = list
}
//创建Holder
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TestHolder {
Log.d(sTAG, "onCreateViewHolder")
mCreateNum++
...
}
//绑定数据,如果有复用会直接返回复用的Holder
override fun onBindViewHolder(holder: TestHolder, position: Int) {
mHolderList.add(holder)
Log.d(sTAG, "onBindViewHolder $mCreateNum ${mHolderList.size} ${holder.lastPosition} <-> $position $holder ")
//绑定数据和记录之前position在Holder中
...
}
...
省略掉关键信息,在Adapter初始化添加两个属性变量,mCreateNum ,mHolderList
mCreateNum 在执行onCreateViewHolder的时候会加1
mHolderList 是一个HashSet,在onBindViewHolder方法中把返回来的Holder加入到Set中,我们知道Set不会保存重复对象
itemView左上角表示当前position
右上角表示:lastPosition --> nowPosition (lastPositon默认为-1,还没有复用)
2020-07-17 08:12:02.374 30898-30898/com.example.recyclerviewstudy D/zy.StudyOneAdapter: onCreateViewHolder
2020-07-17 08:12:02.384 30898-30898/com.example.recyclerviewstudy D/zy.StudyOneAdapter: onBindViewHolder mCreateNum=1 mHolderList.size=1 lastPosition=-1 --> nowPosition=0 TestHolder{51b6336 position=0 id=-1, oldPos=-1, pLpos:-1 no parent}
2020-07-17 08:12:02.391 30898-30898/com.example.recyclerviewstudy D/zy.StudyOneAdapter: onCreateViewHolder
2020-07-17 08:12:02.397 30898-30898/com.example.recyclerviewstudy D/zy.StudyOneAdapter: onBindViewHolder mCreateNum=2 mHolderList.size=2 lastPosition=-1 --> nowPosition=1 TestHolder{799136c position=1 id=-1, oldPos=-1, pLpos:-1 no parent}
2020-07-17 08:12:02.400 30898-30898/com.example.recyclerviewstudy D/zy.StudyOneAdapter: onCreateViewHolder
2020-07-17 08:12:02.406 30898-30898/com.example.recyclerviewstudy D/zy.StudyOneAdapter: onBindViewHolder mCreateNum=3 mHolderList.size=3 lastPosition=-1 --> nowPosition=2 TestHolder{14ca988 position=2 id=-1, oldPos=-1, pLpos:-1 no parent}
2020-07-17 08:12:02.408 30898-30898/com.example.recyclerviewstudy D/zy.StudyOneAdapter: onCreateViewHolder
2020-07-17 08:12:02.413 30898-30898/com.example.recyclerviewstudy D/zy.StudyOneAdapter: onBindViewHolder mCreateNum=4 mHolderList.size=4 lastPosition=-1 --> nowPosition=3 TestHolder{8e63464 position=3 id=-1, oldPos=-1, pLpos:-1 no parent}
2020-07-17 08:12:02.417 30898-30898/com.example.recyclerviewstudy D/zy.StudyOneAdapter: onCreateViewHolder
2020-07-17 08:12:02.422 30898-30898/com.example.recyclerviewstudy D/zy.StudyOneAdapter: onBindViewHolder mCreateNum=5 mHolderList.size=5 lastPosition=-1 --> nowPosition=4 TestHolder{231f000 position=4 id=-1, oldPos=-1, pLpos:-1 no parent}
2020-07-17 08:12:02.425 30898-30898/com.example.recyclerviewstudy D/zy.StudyOneAdapter: onCreateViewHolder
2020-07-17 08:12:02.430 30898-30898/com.example.recyclerviewstudy D/zy.StudyOneAdapter: onBindViewHolder mCreateNum=6 mHolderList.size=6 lastPosition=-1 --> nowPosition=5 TestHolder{27ad85c position=5 id=-1, oldPos=-1, pLpos:-1 no parent}
2020-07-17 08:12:02.433 30898-30898/com.example.recyclerviewstudy D/zy.StudyOneAdapter: onCreateViewHolder
2020-07-17 08:12:02.439 30898-30898/com.example.recyclerviewstudy D/zy.StudyOneAdapter: onBindViewHolder mCreateNum=7 mHolderList.size=7 lastPosition=-1 --> nowPosition=6 TestHolder{9e6a978 position=6 id=-1, oldPos=-1, pLpos:-1 no parent}
- 初始log可以看出:onCreateViewHolder和onBindViewHolder 是成对出现的,这个时候还没有可以复用的元素,几乎是需要,就新建一个,给到onBindViewHolder 进行数据绑定和展示
- lastPosition都是-1说明该Holder还没有复用,属于新建的Holder
- 还有一个现象:不知道大家有没有发现,真个屏幕展示个ItemView的个数是6+1(只有一点点),而Holder生成了7个,说明像这种没有展示完全的ItemView也是已经创建
再测试一下滑动过程中的log表现
2020-07-17 08:27:08.265 30898-30898/com.example.recyclerviewstudy D/zy.StudyOneAdapter: onCreateViewHolder
2020-07-17 08:27:08.271 30898-30898/com.example.recyclerviewstudy D/zy.StudyOneAdapter: onBindViewHolder mCreateNum=11 mHolderList.size=11 lastPosition=-1 --> nowPosition=10 TestHolder{f43dac position=10 id=-1, oldPos=-1, pLpos:-1 no parent}
2020-07-17 08:27:08.281 30898-30898/com.example.recyclerviewstudy D/zy.StudyOneAdapter: onBindViewHolder mCreateNum=11 mHolderList.size=11 lastPosition=0 --> nowPosition=11 TestHolder{51b6336 position=11 id=-1, oldPos=-1, pLpos:-1 no parent}
2020-07-17 08:27:08.289 30898-30898/com.example.recyclerviewstudy D/zy.StudyOneAdapter: onBindViewHolder mCreateNum=11 mHolderList.size=11 lastPosition=1 --> nowPosition=12 TestHolder{799136c position=12 id=-1, oldPos=-1, pLpos:-1 no parent}
2020-07-17 08:27:08.305 30898-30898/com.example.recyclerviewstudy D/zy.StudyOneAdapter: onBindViewHolder mCreateNum=11 mHolderList.size=11 lastPosition=2 --> nowPosition=13 TestHolder{14ca988 position=13 id=-1, oldPos=-1, pLpos:-1 no parent}
2020-07-17 08:27:08.311 30898-30898/com.example.recyclerviewstudy D/zy.StudyOneAdapter: onBindViewHolder mCreateNum=11 mHolderList.size=11 lastPosition=3 --> nowPosition=14 TestHolder{8e63464 position=14 id=-1, oldPos=-1, pLpos:-1 no parent}
2020-07-17 08:27:08.323 30898-30898/com.example.recyclerviewstudy D/zy.StudyOneAdapter: onCreateViewHolder
2020-07-17 08:27:08.329 30898-30898/com.example.recyclerviewstudy D/zy.StudyOneAdapter: onBindViewHolder mCreateNum=12 mHolderList.size=12 lastPosition=-1 --> nowPosition=15 TestHolder{bf047c8 position=15 id=-1, oldPos=-1, pLpos:-1 no parent}
2020-07-17 08:27:08.342 30898-30898/com.example.recyclerviewstudy D/zy.StudyOneAdapter: onBindViewHolder mCreateNum=12 mHolderList.size=12 lastPosition=5 --> nowPosition=16 TestHolder{27ad85c position=16 id=-1, oldPos=-1, pLpos:-1 no parent}
2020-07-17 08:27:08.356 30898-30898/com.example.recyclerviewstudy D/zy.StudyOneAdapter: onBindViewHolder mCreateNum=12 mHolderList.size=12 lastPosition=6 --> nowPosition=17 TestHolder{9e6a978 position=17 id=-1, oldPos=-1, pLpos:-1 no parent}
2020-07-17 08:27:08.372 30898-30898/com.example.recyclerviewstudy D/zy.StudyOneAdapter: onBindViewHolder mCreateNum=12 mHolderList.size=12 lastPosition=7 --> nowPosition=18 TestHolder{51bd34a position=18 id=-1, oldPos=-1, pLpos:-1 no parent}
2020-07-17 08:27:08.388 30898-30898/com.example.recyclerviewstudy D/zy.StudyOneAdapter: onBindViewHolder mCreateNum=12 mHolderList.size=12 lastPosition=8 --> nowPosition=19 TestHolder{cbcbc87 position=19 id=-1, oldPos=-1, pLpos:-1 no parent}
2020-07-17 08:27:08.405 30898-30898/com.example.recyclerviewstudy D/zy.StudyOneAdapter: onBindViewHolder mCreateNum=12 mHolderList.size=12 lastPosition=9 --> nowPosition=20 TestHolder{bc8ec50 position=20 id=-1, oldPos=-1, pLpos:-1 no parent}
2020-07-17 08:27:08.424 30898-30898/com.example.recyclerviewstudy D/zy.StudyOneAdapter: onBindViewHolder mCreateNum=12 mHolderList.size=12 lastPosition=10 --> nowPosition=21 TestHolder{f43dac position=21 id=-1, oldPos=-1, pLpos:-1 no parent}
2020-07-17 08:27:08.439 30898-30898/com.example.recyclerviewstudy D/zy.StudyOneAdapter: onBindViewHolder mCreateNum=12 mHolderList.size=12 lastPosition=11 --> nowPosition=22 TestHolder{51b6336 position=22 id=-1, oldPos=-1, pLpos:-1 no parent}
分析一下LOG给我们提供的信息
- 当我们滑动到一定的时候,就不再调用onCreateViewHolder
- mCreateNum和mHolderList.size也不再增加,保持一个数值不变,且他们相等
- lastPosition的值不在是-1
- mCreateNum=12 mHolderList.size=12 lastPosition=8 --> nowPosition=19 比如这一条log,可以看出复用之前展示8,现在展示19
那就有问题:
- 复用的逻辑是什么?比如,lastPosition=8 --> nowPosition=19
- 缓存的个数是多少? 本次实验是总共是12,全屏展示的是6+1,有什么公式吗?如y=2*x -2?
当然以上都是猜测,后续我们就带着问题来分析复用逻辑