注释1部分:复用ListView的 convertView
(1)如果为空,为其创建一个布局和ViewHolder
(一个装载着布局的容器),然后通过 findViewById()
找到目标控件,将convertView和目标控件装进ViewHolder,通过 setTag()
装到view中去。
(2)如果不为空,从convertView中取出 ViewHolder
注释2部分:让数据源给设置数据,设置在 ViewHolder的成员----目标控件中去。
对比上节中的两块代码,我们发现实现了 ViewHolder的代码和不实现的只有一个区别:
不实现ViewHolder的getView无论如何,每次都要通过findViewById去寻找目标控件,而使用了ViewHolder之后,它不用每次都做findViewById()
去寻找目标控件,这也正是ViewHolder解决的问题。
这也解答了为什么使用了ViewHolder能提高性能?
findViewByI![](https://www.hualigs.cn/image/61dba891ed8ee.jpg) d
在Android底层,所有资源ID应该是以树的形式存储的,然后这个方法实现是通过 DFS去寻找目标控件的,DFS的时间复杂度是 O(n)。
O(n)的复杂度对于程序开发来说,其实是算快的,但是在convertView非常多,view里面的控件也非常多,那每次getView都时候都要调用findViewById,这对性能来说还是会容易产生大量的消耗。
所以ViewHolder的出现,就是为了减少findViewById()
的使用。
我之前也误解,以为一个 ViewHolder里面会存放多个View,但通过上面的代码就知道我是错的。
ViewHolder和View就是一对一的关系,ViewHolder里面装的不是多个View,而是一个View和它里面的控件。是这样的:
在RecyclerView里面也是如此,它和ListView不同之处是在于它让Adapter强制的依赖于ViewHolder,也就是要我们强制使用。
========================================================================================
RecyclerView的缓存机制是一个较为庞大的体系,这里不会去具体解析源码,但是会了解RecyclerView是如何缓存的。
由于ListView也是由它的缓存机制,并且比RecyclerView简单很多。而且RecyclerView缓存的本质和ListView的是差不多的。
所以我先从简单的ListView看起。