ListView性能优化

ListView性能优化

ListView是Android中一个很重要的控件,好多信息的展示都是通过ListView。在我们使用listView的时候,需要注意的也很多。特别是在数据特别多的时候,就要求我们更加注重对ListView的优化,以提高性能。下面我将自己使用ListView的三个阶段分享给大家。希望给大家借鉴。

为了简单说明问题,我在这将listview显示的内容简单化。

如下图所示:
listview

我们来看下adapter的代码.

阶段一

class MyAdapter extends BaseAdapter{

    @Override
    public int getCount() {
        return mData.size();
    }

    @Override
    public Object getItem(int position) {
        return mData.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

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


       View view = mLayoutInflater.inflate(R.layout.viewholder_item,null);
       TextView mTextView = (TextView) view.findViewById(R.id.textview);
        //下面给TextView设置内容
        mTextView.setText(mData.get(position));
       return view;
    }

}

第一种这样写过一段时间,但是后来当ListView条目增多的时候,就会出现明显地卡顿,于是意识到需要对listview进行优化。

阶段二

class MyAdapter extends BaseAdapter{

    @Override
    public int getCount() {
        return mData.size();
    }

    @Override
    public Object getItem(int position) {
        return mData.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

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


        if(null == convertView){


            convertView = mLayoutInflater.inflate(R.layout.viewholder_item,null);

        }
         TextView mTextView = (TextView)convertView.findViewById(R.id.textview);
        //下面给TextView设置内容
        mTextView.setText(mData.get(position));
        return convertView;
    }

}

基于阶段一,对Listview进行了简单的研究,每当我滑动出现新的条目的时候就会调用getView方法,这样做会导致每次都会重新加载布局。加载布局是个比较耗时的操作,特别是条目较多或者频繁滑动的时候。

于是观察了下getView中存在三个参数,其中有一个convertView参数,通过查资料知道了,这个参数用来对条目的View进行缓存,当我第一次使用的时候convertView==null,当第二次或者多次调用的时候,convertView!= null。这个时候我们就可以将缓存的view利用起来,避免了重复加载布局引起的性能问题。

阶段三

class MyAdapter extends BaseAdapter{

    @Override
    public int getCount() {
        return mData.size();
    }

    @Override
    public Object getItem(int position) {
        return mData.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

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

        ViewHolder holder = null;
        if(null == convertView){

            holder = new ViewHolder();
            convertView = mLayoutInflater.inflate(R.layout.viewholder_item,null);
            holder.mTextView = (TextView) convertView.findViewById(R.id.textview);
            convertView.setTag(holder);
        }else{

            holder = (ViewHolder) convertView.getTag();
        }
        //下面给TextView设置内容
        holder.mTextView.setText(mData.get(position));
        return convertView;
    }


    private final class ViewHolder{

        private TextView mTextView;
    }
}

有了第二个阶段,自以为listview使用不过如此,优化也很简单啊。但是细心的就会发现,我们这样做虽然对缓存的convertView进行了重复利用,但是会反复的findViewbyId查找我们需要操作的控件。这个操作也是比较耗时的,特别是在条目比较多的时候。所以第三种方式诞生,通过这种方式我们避免了重复查找条目中的控件,达到性能的进一步提升。