利用ConvertView和ViewHolder提升ListView的运行效率

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 {
    private int resourceId;
    public FruitAdapter( Context context,  int resource,  List 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;
    }
}

你可能感兴趣的:(利用ConvertView和ViewHolder提升ListView的运行效率)