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

原创 2015年07月06日 18:07:35

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

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

android BaseAdapter 自定义适配器 BaseAdapter基类抽取 一

android BaseAdapter 自定义适配器 BaseAdapter基类抽取 一

适配器基类--万能适配器(BaseAdapter)

一个抽象类继承BaseAdapter package com.lei.adapter; import java.util.ArrayList; import java.util.List; i...

Android快速开发框架Android_BaseLib,集成了常用工具类,自定义View控件,Base基类封装,常用开源框架

Android_BaseLib 这是一个用于Android快速开发的框架,主要是在以往的项目开发中,收集到的常用的功能: 1.常用到的工具类; 2.BaseActivit...

android 自定义适配器Adapter基类BaseAdapter

AdapterView中经常用到适配器Adapter,而anroid提供的Adapter只是几种框架,如果我们有需求,还是要自己根据需求而自定义Adapter的。 android提供的三种Adapt...

android BaseAdapter 自定义适配器 BaseAdapter基类抽取 二

android BaseAdapter 自定义适配器 BaseAdapter基类抽取 二

如何优雅的写代码——使用RecyleView的基类Adapter

使用基类是代码更清晰也更简单,就是容易看也容易写。平常写个Adapter可能又长又乱,现在可以这样写了: public class AppListAdapter extends RecycleVar...

继承RecyclerView.Adapter使用泛型遇到的问题

转自:http://my.oschina.net/buobao/blog/651007 在使用RecyclerView的时候遇到了一个很坑的问题,记录这个大坑! 首先,在使用RecyclerVie...

Java泛型 类型变量的限定

有时候,类和方法需要对类型变量加以约束,比如你有一个方法,你只希望它接收某个特定类型及其子类型作为参数。 下面就举一个方法限定接收参数的类型的例子来说明如何限定类型变量。 首先有几个简单的辅助类: p...

泛型与反射的使用总结之反射篇

前一篇对泛型进行了一番总结,本篇就来说说与泛型有关的反射。     我在泛型篇中说到了泛型在JVM中是会被擦除的,不过擦除的类还是“残留”了一些泛型的痕迹。比如Person类,虽然擦除掉了泛型,但是...

利用泛型、反射、JPA、Spring技术实现增删改查通用类

1、定义接口 package cn.joeho.base; import java.io.Serializable; public interface DAO {  public String...
  • joeho
  • joeho
  • 2012-06-24 09:45
  • 2328
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)