当前位置:  编程语言>java/jsp

andriod中ListView, listItem布局和convertView的缓存与重用详解

 
    发布时间:2014-2-7  


    本文导语:  在android开发中ListView是比较常用的组件,它以列表的形式展示具体内容,并且能够根据数据的长度自适应显示。列表的显示需要三个元素:1.ListVeiw:用来展示列表的View。2.适配器:用来把数据映射到ListView上的中介。...

    在android开发ListView是比较常用的组件,它以列表的形式展示具体内容,并且能够根据数据长度自适应显示。列表的显示需要三个元素:

1.ListVeiw:用来展示列表的View

2.适配器:用来把数据映射到ListView上的中介。

3.数据:具体的将被映射的字符串图片,或者基本组件。

根据列表的适配器类型,列表分为三种,ArrayAdapterSimpleAdapterSimpleCursorAdapter其中以ArrayAdapter最为简单,只能展示一行字。SimpleAdapter有最好的扩充性,可以自定义出各种效果SimpleCursorAdapter可以认为是SimpleAdapter对数据库的简单结合,可以方面的把数据库的内容以列表的形式展示出来。

    convertViewAPI中的解释是The old view to reuse, if possible, 第一次getView时还没有convertView,这时你便创建了一个新的view,下次getView时就有这个“旧的”convertView了  setTag的作用才是把查找的view通ViewHolder封装缓存起来方便多次重用,当需要时可以getTag拿出来

   最近有需求需要在listView中载入不同的listItem布局,若这样写

public View getView(int position, View convertView, ViewGroup parent) {
 View view = new Xxx(...);
 ... ...
 return view;
}

没有使用缓存的 convertView,会导致内存泄露

以构造ListViewBaseAdapter为例,在BaseAdapter中提供了方法

public View getView(int position, View convertView, ViewGroup parent){ }

来向ListView提供每一个item所需要的view对象。初始时ListView会从BaseAdapter中根据当前的屏幕布局实例化一定数量的view对象,同时ListView会将这些view对象缓存起来。当向上滚动ListView时,原先位于最上面的list itemview对象会被回收,然后被用来构造新出现的最下面的list item。这个构造过程就是由getView()方法完成的,getView()的第二个形参 View convertView就是被缓存起来的list itemview对象(初始化时缓存中没有view对象则convertView编程技术其它 iis7站长之家)由此可以看出,如果我们不去使用convertView,而是每次都在getView()中重新实例化一个View对象的话,即浪费资源也浪费时间,也会使得内存占用越来越大。

修正示例代码:
public View getView(int position, View convertView, ViewGroup parent) {
 View view = null;
 if (convertView != null) {
 view = convertView;
 ...
 } else {
 view = new Xxx(...);
 ...
 }
 return view;
}

上述代码很好的解决了内存泄露的问题,使用convertView回收一些布局供下面重构是使用。

convertViewItem为单一的布局时,能够回收并重用,但是多个Item布局时,convertView的回收和重用会出现问题。

Listview中有3种Item布局,即使convertView缓存了一些布局,但是在重构时,根本不知道怎么样去让convertView返回你所需要的布局,这时你需要让adapter知道我当前有哪些布局,我重构Item时的布局选取规则,好让convertView能返回你需要的布局需要重写一下两个函数

@Override

public int getItemViewType(int position) {}

上述两个函数的作用这如它的名字,得到Item样式,得到所有的样式数量。

    在getView()中需要将不同布局进行缓存和适配,系统判断是否有convertView时,会自动去调用getItemViewType (int position) ,查看是否已经有缓存的该类型的布局,从而进入if(convertView == null)和else{}的判断。期间需要做的是convertView.setTag(holder3),以便在convertView重用时可以直接拿到该布局的控件,holder3 = (viewHolder3) convertView.getTag()。到这一步,convertView的回收和重用就已经写好了,接下来只需要对你的不同的控件进行设置就行了。

    您可能感兴趣的文章:

相关文章推荐:


站内导航:


特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

©2012-2021,,E-mail:www_#163.com(请将#改为@)

浙ICP备11055608号-3