ListView 绝对可以称得上是Android中最常用的控件之一,几乎所有的程序都会用到它。要学好ListView,不但要学习如何使用它,还要学习怎么用好它。下面写的内容主要是围绕如何优化listview的运行效率。
1. 利用getview()方法中的convertView参数进行优化
在ListView滑动的过程中,很容易就会发现每次getView()被执行都会new出一个View对象 长此以往会产生很大的消耗 ,特别当item中还有Bitmap等 甚至会造成OOM的错误导致程序崩溃。
利用convertView参数可以将之前加载好的布局进行缓存,以便之后可以进行重用。我们可以在getview()方法中进行判断,如果convertview为null,则使用layoutinflater去加载布局,如果不为null则直接对convertView进行重用。原理上来讲就是,当ListView滑动的过程中会有item被滑出屏幕,不再被使用。这时候Android会回收这个条目的view,这个view也就是这里的convertView,使屏幕中始终保持只有几个。
2. 利用ViewHolder进行优化
在Adapter中新增一个内部类ViewHolder,用于进行实例的缓存。当convertview为null 的时候,创建一个ViewHolder对象。并将控件的实例都存放在ViewHolder里,然后把ViewHolder存放在View中。当convertview不为null的时候,调用view中的gettag方法把viewholder,就没必要通过findbyid(0获取控件实例了。
使用了以上这两种方法进行优化之后,listview的运行效率已经就非常不错了。
public class FruitAdapter extends ArrayAdapter<Fruit> {
private int resourceId;
public FruitAdapter( Context context, int resource, List<Fruit> objects) {
super(context, resource, objects);
this.resourceId = resource;
}
@NonNull
@Override
public View getView(int position, View convertView, ViewGroup parent) {
Fruit fruit = getItem(position); //获取当前项的Fruit实例
View view;
ViewHolder viewHodler;
if(convertView==null){ // 优化:不会重复加载布局
view = LayoutInflater.from(getContext()).inflate(resourceId,parent,false);
viewHodler = new ViewHolder(); //优化:不会重复调用findviewbyid方法获取控件
viewHodler.fruitName = (TextView) view.findViewById(R.id.Name);
view.setTag(viewHodler); //将ViewHolder存在View中
}
else{
view =convertView;
viewHodler = (ViewHolder) view.getTag();
}
viewHodler.fruitName.setText(fruit.getName());
return view;
}
class ViewHolder{
TextView fruitName;
}
}