Android中的列表视图应该算是布局中几种最常用的组件之一了,使用也十分方便、下面将介绍ListView几种比较常见的优化方法:
首先我们给出一个没有任何优化的列表视图的适配器类,我们这里都继承自BaseAdapter,这里我们使用一个包含100个字符串的列表集合来作为Listview的项目所要显示的内容,每一个条目都是一个自定义的组件,这个组件中只包含一个textview:
活动:
包com.alexchen.listviewoptimize; 进口java.util.ArrayList; 进口并不知道; 进口android.app.Activity; 进口android.os.Bundle; 进口android.view.Menu; 进口android.view.MenuItem; 进口android.view.View; 进口android.view.ViewGroup; 进口android.widget.BaseAdapter; 进口android.widget.ListView; 进口android.widget.TextView; 公开课MainActivity延伸活动{ 私人ListView lv_demo; 私人List列表; @Override 保护空白> @Override 公众视线getView (int位置、视图convertView ViewGroup父){ 视图视图;//判断convertView的状态,来达到复用效果 如果(null==convertView) {//如果convertView为空,则表示第一次显示该条目,需要创建一个视图=View.inflate (MainActivity视图。R.layout.listview_item,这 零); 其他}{//否则表示可以复用convertView 视图=convertView; }//listview_item里只有一个textview TextView tv_item=(TextView) view.findViewById (R.id.tv_item); tv_item.setText (list.get(位置)); 返回视图; } >之前
上面是对视图对象的复用做的优化,我们经过上面的优化之后,我们不需要每一个视图都重新生成了。下面我们来解决下一个每一次都需要做的工作,那就是视图中组件的查找:
TextView tv_item=(TextView) view.findViewById (R.id.tv_item);实际上,findViewById是到xml文件中去查找对应的id,可以想象如果组件多的话也是挺费事的,如果我们可以让视图内的组件也随着视图的复用而复用,那该是多美好的一件事啊,实际上谷歌也推荐了一种优化方法来做应对,那就是重新建一个内部静态类,里面的成员变量跟视图中所包含的组件个数类型相同,我们这里的视图只包含了一个TextView,所以我们的这个静态类如下:
私有静态类ViewHolder { 私人TextView tvHolder; }那么这个viewHolder类我们要如何使用才可以达到复用效果呢?基本思路就是在convertView为零的时候,我们不仅重新膨胀出来一个视图,并且还需要进行findviewbyId的查找工作,但是同时我们还需要获取一个viewHolder类的对象,并将findviewbyId的结果赋值给viewHolder中对应的成员变量。最后将持有人对象与该视图对象“绑”在一块。
当convertView不为空时,我们让视图=converView,同时取出这个视图对应的持有人对象,就获得了这个视图对象中的TextView组件,它就是持有人中的成员变量,这样在复用的时候,我们就不需要再去findViewById了,只需要在最开始的时候进行数次查找工作就可以了。这里的关键在于如何将视图与持有人对象进行绑定,那么就需要用到两个方法:setTag和getTag方法了:
@Override 公众视线getView (int位置、视图convertView ViewGroup父){ 视图视图; ViewHolder持有人;//判断convertView的状态,来达到复用效果 如果(null==convertView) {//如果convertView为空,则表示第一次显示该条目,需要创建一个视图=View.inflate (MainActivity视图。R.layout.listview_item,这 零);//新建一个viewholder对象 持有人=new ViewHolder ();//将findviewbyID的结果赋值给持有人对应的成员变量 持有人。tvHolder=(TextView) view.findViewById (R.id.tv_item);//将支架与视图进行绑定 view.setTag(持有人); 其他}{//否则表示可以复用convertView 视图=convertView; 持有人=(ViewHolder) view.getTag (); }//直接操作夹中的成员变量即可,不需要每次都findViewById holder.tvHolder.setText (list.get(位置)); 返回视图; } >之前经过上面的做法,可能大家感觉不太到优化的效果,根据谷歌的文档,实际优化效果在百分之5左右。
Android中列表视图的几种常见的优化方法总结