ListView优化adapter getview的两种方式ViewHolder vs HolderView

泡在网上的日子 / 文 发表于2014-10-21 15:02 次阅读 ListView

一、ViewHolder方式

如果你还没听说过ViewHolder,那么你该去好好看看官方文档了,而不是埋头写代码。

一个ListView的item布局中需要赋值的子元素太多为了避免重复的调用FindViewById方法,我们一般考虑使用ViewHolder方式来实现BaseAdapter。

如下:

//在外面先定义,ViewHolder静态类
static class ViewHolder
{
    public ImageView img;
    public TextView title;
    public TextView info;
}
//然后重写getView
@Override
public View getView(int position, View convertView, ViewGroup parent) {
    ViewHolder holder;
    if(convertView == null)
    {
        holder = new ViewHolder();
        convertView = mInflater.inflate(R.layout.list_item, null);
        holder.img = (ImageView)item.findViewById(R.id.img)
        holder.title = (TextView)item.findViewById(R.id.title);
        holder.info = (TextView)item.findViewById(R.id.info);
        convertView.setTag(holder);
    }else
    {
        holder = (ViewHolder)convertView.getTag();
    }
        holder.img.setImageResource(R.drawable.ic_launcher);
        holder.title.setText("Hello");
        holder.info.setText("World");
    }
                                                                                                                                                                                                                                                                                                                                               
    return convertView;
}

ViewHolderconvertView第一次inflate的时候绑定了相关的子元素,并被convertView保存下来(setTag方法),当相同的convertView再次需要显示的时候直接调用convertView的getTag取出ViewHolder,并对ViewHolder中的元素赋值。使用ViewHolder模式避免了没有必要的调用findViewById():因为太多的findViewById也会影响性能,这点不容易考虑到。


二、HolderView方式

在HolderView方式中,目的同样是为了避免反复的调用findViewById,但是我们将这个findViewByIdde 任务交给了一个HolderView对象

@Override
public View getView(int i, View convertView, ViewGroup viewGroup) {
    HolderView holderView;
    // Important to not just null check, but rather to a instanceof
    // since we might get any subclass of view here.
    if (convertView instanceof HolderView) {
        holderView = (HolderView) convertView;
    } else {
        holderView = new HolderView(mContext);
    }
    holderView.bind("标题", R.drawable.ic_launcher, "sajsa");
    return holderView;
}
public class HolderView extends GridLayout {
    private ImageView img;
    private TextView title;
    private TextView info;
    public HolderView(Context context, AttributeSet attrs) {
        super(context, attrs);
        View v = LayoutInflater.from(context).inflate(R.layout.list_item, this);
        title = (TextView) v.findViewById(R.id.title);
        img = (ImageView)item.findViewById(R.id.img)
        info = (TextView)item.findViewById(R.id.info);
    }
    public void bind(String stringtitle,int imgrsc, String stringinfo) {
        title.setText(stringtitle);
        img.setImageResource(imgrsc);
        info.setText(stringinfo);
    }
}

HolderView自己维护一个子元素的集合,同时对外提供绑定数据的公共方法bind。HolderView方式的思想是:对于ListView来讲,每一个Item本身是同一个类只是数据不同。但是需要注意的是使用HolderView方式在Adapter中getView返回的是HolderView对象。

总结:ViewHolder方式使用简单,HolderView方式更符合面向对象规范。

收藏 赞 (1) 踩 (1)
上一篇:Fragment的setUserVisibleHint方法实现懒加载
我们在做应用开发的时候,一个Activity里面可能会以viewpager(或其他容器)与多个Fragment来组合使用,而如果每个fragment都需要去加载数据,或从本地加载,或从网络加载,那么在这个activity刚创建的时候就变成需要初始化大量资源。这样的结果,我们当然不
下一篇:ListView之BaseAdapter的基本使用以及ViewHolder模式
这篇文章适合初学者,高手绕道,当然不知道ViewHolder的“高手”可以停下来。 话说开发用了各种Adapter之后感觉用的最舒服的还是BaseAdapter,尽管使用起来比其他适配器有些麻烦,但是使用它却能实现很多自己喜欢的列表布局,比如ListView、GridView、Galler