利用Android反射与泛型机制写一个通用的Adapter类

来源:互联网 发布:对象数组的指针 编辑:程序博客网 时间:2024/05/01 09:47

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

0 0
原创粉丝点击