ListView的缓存机制

  • 内容
  • 评论
  • 相关

在Android开发中,最常用的控件就是ListView了,使用BaseAdapter创建自定义适配器时,覆写public View getView(int position, View convertView, ViewGroup parent)的时候,往往都是根据第一个参数position来获取对应item的数据,然后使用View.inflate()来创建一个View,试想一下,如果ListView有很多的Item,岂不是每一个Item都需要创建一个View,这样肯定是不够优雅的,优雅的实现就需要使用到ListView的缓存机制了

什么是ListView的缓存机制?

假设当前手机屏幕只能显示ListView中的7个Item,当ListView刚开始显示时,系统会调用7次适配器中的getView()来获取其对应的View显示在屏幕上,当ListView开始向上滑动的时候,会再次调用getView()来显示第8个Item,当第一个Item从屏幕上不可见时,第一个Item对应的View并不是被回收了,而是被放入了一个缓存区Recycle,当第8个Item要显示的时候,getView()的第二个参数convertView就会把缓存区中的View传递过来,供重复使用,如下图

listView02

 

 

 

 

 

 

 

 

 

LsitView缓存机制的验证

自定义适配器的布局创建请参见:   BaseAdapter自定义适配器  这里只给出改变了的getView方法

Log日志(屏幕上可见0-8的item)

listView04

当ListView初次显示的时候,缓冲区为空getView()的第二个参数为null,当,第9项显示,第一项未完全不可见的时候,缓冲区依然为null,当第一项不可见以后,可以看到,position=10的View.hashCode()与第一项相同,同时缓冲区不为null,这样,不论有多少项,在内存中只需要屏幕可见项+1数量的View即可

自定义适配器的优化一

逗比式做法就是每一次都新建一个View,普通式,就是每一次判断第二个参数convertView是否为空,也就是缓冲区是否存在View,没有则创建,有则直接使用

自定义适配器优化二

优化一中,每一次都需要从convertView中使用findViewById()方法去获取控件,当布局文件很复杂时,这无疑也是加大了时间成本,还有一种方法是用空间换取时间,定义一个内部类ViewHolder对应每一个Item的控件,然后通过convertView的的setTag()方法保存,使用的时候通过getTag()直接获取ViewHolder,这样除了第一次需要findViewById()以外,以后都可以不用了,这也是谷歌推荐的做法

源码下载:360云盘    访问密码 fe60

评论

0条评论

发表评论

邮箱地址不会被公开。