ListView是在Android开发中使用频率极高的高级控件,现在看来只要使用频率高的东西,那么就有必要去封装,封装到别人容易看懂,自己写的代码少,方便这样就可以。
下面给大家分享下我自己的adapter的封装,封装之前当然得先封装ViewHolder,减少findViewById以及复用布局。
CommonViewHolder类:
public class CommonViewHolder {
public View convertView;
SparseArray<View> 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 extends View> T getView(int id) {
if (views.get(id) == null) {
views.put(id, convertView.findViewById(id));
}
return (T) views.get(id);
}
@SuppressWarnings("unchecked")
public <T extends View> T getView(int id, Class<T> klass) {
return (T) getView(id);
}
使用时只需要传入布局文件id和需要找到的View控件.class文件即可,不再需要自己去强转
再看看Adapter的封装
public abstract class BaseListViewAdapter<T> extends BaseAdapter {
protected List<T> 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<String> {
public MyAdapter(Context context, List<String> datas){
this.datas=datas;
this.mContext=context;
}
public void updateUi(List<String> 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;
}
}