注意點: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);