ListView的优化(一)

ListView的优化(一)

   接下来的几章我将主要讲一下关于ListView的优化,尽管如今更多的是recyclerview,但是ListView的使用还是很多的,毕竟是老大哥,接下来直奔主题。
   首先,来看一下未优化 之前的Listview的使用,代码贴上。
public class ListViewAdapter extends BaseAdapter {
    private List<String> mData;
    private Context context;
    private LayoutInflater mInflater;
    public ListViewAdapter(Context context,List<String> mData){
        this.context = context;
        this.mData = mData;
        mInflater = LayoutInflater.from(context);
    }
    @Override
    public int getCount() {
        return mData.size();
    }

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

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

    @Override
    public View getView(int i, View view, ViewGroup viewGroup) {
            view = mInflater.inflate(R.layout.item,null);
            TextView tv = view.findViewById(R.id.item_tv);
            ImageView img = view.findViewById(R.id.item_img);
            tv.setText(mData.get(i));
            return view;
    }
}

这里主要分析
public View getView(int i, View view, ViewGroup viewGroup)
该方法主要是用于获取对应位置i的组件,并设置组件数据。但是在每一个位置i获取对应位置组件是都会调用getView()方法,也就意味着每次都会实例化一个view对象,这个view对象也就是我们listView的每一个item对用的组件(在这里也就是item.xml布局文件中对用的父组件),而这个viw在每次调用getView()时都会实例化一次,同时View这个父组件中的TextView和ImageView每次也重新实例化一个对象。
这样在item数目较多时就会创建很多个view,因此效率很低。
而由于每一个item对应的组件其实都是一样的,都是一个TextView和ImageView,因此如果我们可以重复利用这些已经实例化的组件,就可以少创建很多对象,效率自然 也就提高了。

    具体如下:
 
public class ListViewAdapter extends BaseAdapter {
    private List<String> mData;
    private Context context;
    private LayoutInflater mInflater;
    public ListViewAdapter(Context context,List<String> mData){
        this.context = context;
        this.mData = mData;
        mInflater = LayoutInflater.from(context);
    }
    @Override
    public int getCount() {
        return mData.size();
    }

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

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

    @Override
    public View getView(int i, View view, ViewGroup viewGroup) {
        ViewHolder holder = null;
        if(view==null){
            holder = new ViewHolder();
            
 ViewHolder holder = null;
        if(view==null){
            holder = new ViewHolder();
            view = mInflater.inflate(R.layout.item,null);
            holder.txt = view.findViewById(R.id.item_tv);
            holder.img = view.findViewById(R.id.item_img);
            view.setTag(holder);
        }else {
            holder = (ViewHolder) view.getTag();
        }
        holder.txt.setText(mData.get(i));
        return view;
holder.txt = view.findViewById(R.id.item_tv); holder.img = view.findViewById(R.id.item_img); view.setTag(holder); }else { holder = (ViewHolder) view.getTag(); } holder.txt.setText(mData.get(i)); return view; } private class ViewHolder{ public ImageView img; public TextView txt; }}
 
  

这里我们创建一个ViewHolder类,ViewHolder并不是Android的API,而是Android Demo中示范代码,通过定义一个ViewHolder来包含每一个item中的所有组件,在ViewHolde定义了item中的组件,在ViewHolder中保存着所有组件的引用,再通过setTag()将这个ViewHolder附加在view上,如下在getView()方法中

ViewHolder holder = null;

 
 
        if(view==null){
            holder = new ViewHolder();
            view = mInflater.inflate(R.layout.item,null);
            holder.txt = view.findViewById(R.id.item_tv);
            holder.img = view.findViewById(R.id.item_img);
            view.setTag(holder);
        }else {
            holder = (ViewHolder) view.getTag();
        }
        holder.txt.setText(mData.get(i));
        return view;

通过判断view是否等于null,如果等于null,那么表示这个view不存在,则创建view,并根据view来执行findViewById()实例化ViewHolder中的TextView和ImageView,在首次实例化View后,设置view.setTag(),将带有子组件引用的ViewHolder附加到View上,从而达到一个视图缓存的目的。这样在下次加载时直接调用getTag()即可取出对应的组件,从而避免多次实例化白白浪费内存。

猜你喜欢

转载自blog.csdn.net/ckq5254/article/details/78045231