ListView的Adapter的封装以及ViewHolder的封装

ListView是在Android开发中使用频率极高的高级控件,现在看来只要使用频率高的东西,那么就有必要去封装,封装到别人容易看懂,自己写的代码少,方便这样就可以。
下面给大家分享下我自己的adapter的封装,封装之前当然得先封装ViewHolder,减少findViewById以及复用布局。

CommonViewHolder类:

public class CommonViewHolder {
public View convertView;
SparseArray views = new SparseArray<>();

public CommonViewHolder(View convertView) {
    super();
    this.convertView = convertView;
    convertView.setTag(this);
}

public static CommonViewHolder getCommonViewHolder(View convertView, Context context, int layoutRes) {
    if (convertView != null) {
        return (CommonViewHolder) convertView.getTag();
    } else {
        convertView = View.inflate(context, layoutRes, null);
        return new CommonViewHolder(convertView);
    }

}

@SuppressWarnings("unchecked")
public  T getView(int id) {
    if (views.get(id) == null) {
        views.put(id, convertView.findViewById(id));
    }
    return (T) views.get(id);
}

@SuppressWarnings("unchecked")
public  T getView(int id, Class klass) {
    return (T) getView(id);
}
使用时只需要传入布局文件id和需要找到的View控件.class文件即可,不再需要自己去强转

再看看Adapter的封装

public abstract class BaseListViewAdapter extends BaseAdapter {
protected List datas;//数据list,泛型在子类中具体实现
protected ListView mListView;//有时构造中携带listview,方便调用
protected Context mContext;//上下文,构造中必须传值进来

@Override
public int getCount() {
    int num=getAddSize();
    return datas==null?num:datas.size()+num;
}

public int getAddSize(){

    return 0;//默认为0,但出现在头部或者尾部要加个类似添加的条目的时候需要重写,增加1个就return 1,
}

@Override
public T getItem(int position) {
    return datas.get(position);
}

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

@Override
public int getViewTypeCount() {

    return 1;//默认为1,多个不同布局需要重写
}

@Override
public int getItemViewType(int position) {
    return super.getItemViewType(position); //默认为0,多个不同布局需要根据position重写
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    int type=getItemViewType(position);
    CommonViewHolder cvh= CommonViewHolder.getCommonViewHolder(convertView,mContext,getLayoutResId(type));//获取ViewHolder
    setView(cvh,position);
    return cvh.convertView;
}

public abstract void setView(CommonViewHolder cvh, int position);//设置布局中内容显示

public abstract int getLayoutResId(int type);//根据item类型来写layout

}

实际使用案例:

public class MyAdapter extends BaseListViewAdapter {
public MyAdapter(Context context, List datas){
    this.datas=datas;
    this.mContext=context;
}
public void updateUi(List datas){
    this.datas=datas;
    notifyDataSetChanged();
}

@Override
public void setView(CommonViewHolder cvh, int position) {
    cvh.getView(R.id.iv, ImageView.class).setImageResource(R.drawable.ic_launcher);
    String text=String .format(Locale.getDefault(),"测试数据%s",datas.get(position));
    cvh.getView(R.id.tv, TextView.class).setText(text);

}

@Override
public int getLayoutResId(int type) {
    return R.layout.listview_item;
}
}

看,使用起来特别的方便。当遇到布局不同的情况,只需要重写getItemViewType 和getViewTypeCount即可。

你可能感兴趣的:(ListView的Adapter的封装以及ViewHolder的封装)