注意点:Android的反射机制有一个问题,就是Class.getDeclaredFields()返回的变量数组与我们定义的类的变量顺序是不一致的.Android是经过了字母顺序排序的.所以我们需要将变量名传入adapter
//定义一个带泛型的抽象类作为基类,T表示数据类,E表示ViewHolder类
public abstract class TBaseAdapter<T> extends BaseAdapter{
List<T> mList;//用于存放数据集
LayoutInflater mInflater;
Context context;
int [] viewIds;//存放控件ID
String[] fields;//存放ViewHolder类变量的名字
int layoutId;//布局文件ID
Class<?> classOfE;//ViewHolder类
//构造函数
public TBaseAdapter(Context context, List<T> mList) {
// TODO Auto-generated constructor stub
mInflater = LayoutInflater.from(context);
this.mList = mList;
this.context = context;
}
public void setFields(String[] fields) {
this.fields = fields;
}
public void setViewIds(int[] viewIds){
this.viewIds = viewIds;
}
public void setClass(Class<?> e){
this.classOfE = e;
}
public void setLayoutId(int layoutId) {
this.layoutId = layoutId;
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return mList == null ? 0 : mList.size();
}
@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return mList.get(position);
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
//获取布局文件,将控件初始化
public Object initViewHolder(View convertView){
try {
if (fields.length != viewIds.length) {
return null;
}
Object e = classOfE.newInstance();//调用空构造函数
int length = fields.length;
for(int i = 0;i<length;i++){
Field field = classOfE.getDeclaredField(fields[i]);//通过反射获取变量
field.setAccessible(true);//将变量设置为可访问状态
field.set(e,convertView.findViewById(viewIds[i]));//为变量设值
}
return e;
} catch (InstantiationException ex) {
// TODO Auto-generated catch block
ex.printStackTrace();
return null;
} catch (IllegalAccessException ex) {
// TODO Auto-generated catch block
ex.printStackTrace();
return null;
} catch (IllegalArgumentException ex) {
// TODO Auto-generated catch block
ex.printStackTrace();
return null;
} catch (NoSuchFieldException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
return null;
}
}
//抽象方法,实现些方法用于数集的绑定
public abstract void addDataToView(T t,Object o);
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
Object e = null;
if (convertView == null) {
convertView = mInflater.inflate(layoutId, null);
e =initViewHolder(convertView);
if (e!=null)
convertView.setTag(e);
} else
e = convertView.getTag();
addDataToView(mList.get(position),e);
return convertView;
}
}
这样以后写Adapter的时候,只要继承这个类,并实现addDataToView()
方法就可以.然初始化adapter后,传入相应的布局文件ID,控件ID,变量名和ViewHolder类就可以.如下:
Adapter adapter = new Adapter(this, mList);
adapter.setLayoutId(R.layout.item);
int[] ids = {R.id.name,R.id.age,R.id.sex};
String[] fields = {“name”,”age”,”sex”};
adapter.setClass(MyViewHolder.class);
adapter.setViewIds(ids);
adapter.setFields(fields);