当前位置: 首页 > 工具软件 > CommonAdapter > 使用案例 >

Android通用适配器CommonAdapter

尤钱明
2023-12-01

Android通用适配器CommonAdapter

1、刚完成一个小项目,项目中有多个页面,其中包含了许多ListView和GridView,避免不了要写很多的Adapter,当时就像那么多重复的代码,若是抽取一下就好了,由于时间紧迫,没有来得及抽取,刚好前几天看到慕课上《打造万能适配器》,本文算是对该视频的学习记录,按照自己的方式,对视频中的代码进行了稍稍的改动,废话说多了,下面进入主题…
2、Demo源码:http://download.csdn.net/detail/gonghao2014/9704384

1、普通方式

注:这里只给出关键部分代码

//类似ListView这样的视图,继承BaseAdapter实现ListView的适配器类
public class ListViewAdapter extends BaseAdapter {
    private Context mContext;
    private List<Bean> mBeans;
    public ListViewAdapter(Context context, List<Bean> beans) {
        this.mContext = context;
        this.mBeans = beans;
    }

    @Override
    public int getCount() {
        return mBeans.size();
    }

    @Override
    public Object getItem(int position) {
        return mBeans.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        if (convertView == null) {
            convertView = LayoutInflater.from(mContext).inflate(
                    R.layout.item_grid_view, parent, false);
        }
        ViewHolder viewHolder = (ViewHolder) convertView.getTag();
        if (viewHolder == null) {
            viewHolder = new ViewHolder();
            convertView.setTag(viewHolder);
        }
        viewHolder.img = (ImageView) convertView.findViewById(R.id.id_img);
        viewHolder.title = (TextView) convertView.findViewById(R.id.id_title);
        Bean bean = mBeans.get(position);
        viewHolder.img.setImageResource(bean.getImgId());
        viewHolder.title.setText(bean.getTitle());
        return convertView;
    }
    class ViewHolder {
        ImageView img;
        TextView title;
    }
}
//当一个项目中类似这样的ListView和GridView多了以后,会发现要写很多个Adapter类,并且代码很多是重复的
//比如说:Context字段、List<Bean>实体数据字段、构造方法、getCount()、getItem()、getItemId()

1、仔细观察后发现,其实每个Adapter类中,最大的不同点就是用户看到的视图(childView),和视图中填充的数据
2、所以就想,能抽象一个转化方法–convert(视图Id,该视图的显示数据)
3、两个参数:视图Id(viewId)该视图要显示的数据(bean.getXX())
4、写一个抽象类CommonAdapter,让需要使用的Adapter继承CommonAdapter类,重写其中的convert方法即可

2、抽取方式

第一步:新建一个CommonAdapter类,代码如下

/**
 * 通用适配器类
 * @author HaoG
 * @param <T>
 *            要填充的数据类型
 */
public abstract class CommonAdapter<T> extends BaseAdapter {

    private Context mContext; //上下文对象,LayoutInflater加载布局时用到
    private List<T> mBeans; //视图要显示的数据的集合
    private int mLayoutId; //要显示的视图所在的布局的ID

    public CommonAdapter(Context context, List<T> beans, int layoutId) {
        this.mContext = context;
        this.mBeans = beans;
        this.mLayoutId = layoutId;
    }

    @Override
    public int getCount() {
        return mBeans.size();
    }

    @Override
    public Object getItem(int position) {
        return mBeans.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        if (convertView == null) {
            convertView = LayoutInflater.from(mContext).inflate(mLayoutId,
                    parent, false);
        }
        //这里是一个转换器类,下面详细介绍
        Convertor convertor = Convertor.get(convertView);
        //根据上面的想法,抽取出来的抽象方法convert()
        convert(convertor, mBeans.get(position));
        return convertView;
    }

    /**
     * 使用转换器convertor,将数据bean显示在相对应View上
     * 具体的视图和数据的适配依据需求而定,所以具体的实现要交个子类去实现
     * @param convertor
     * @param bean
     */
    public abstract void convert(Convertor convertor, T bean);
}

第二步:新建一个Convertor类,代码如下

/**
 * 转换器类 封装了一个ViewHolder(即mViews)
 * 
 * @author HaoG
 */
public class Convertor {

    private View mConvertView;
    private SparseArray<View> mViews;// viewHolder

    public Convertor(View convertView) {
        mViews = new SparseArray<View>();
        this.mConvertView = convertView;
    }

    /**
     * 获取convertor实例
     * 
     * @param convertView
     * @return
     */
    public static Convertor get(View convertView) {
        Convertor convertor = (Convertor) convertView.getTag();
        if (convertor == null) {
            convertor = new Convertor(convertView);
            convertView.setTag(convertor);
        }
        return convertor;
    }

    /**
     * 根据viewId获取View视图实例
     * 
     * @param viewId
     * @return
     */
    @SuppressWarnings("unchecked")
    private <T extends View> T getView(int viewId) {
        View childView = mViews.get(viewId);
        if (childView == null) {
            childView = mConvertView.findViewById(viewId);
            mViews.put(viewId, childView);
        }
        return (T) childView;

    }

    /**
     * 给指定viewId的TextView控件设置文本
     * 
     * @param viewId
     * @param text
     * @return
     */
    public Convertor setText(int viewId, String text) {
        TextView tv = getView(viewId);
        tv.setText(text);
        //返回值是Convertor类的对象本身是为了代码的书写方便,可以链式书写,下面可以看到链式书写形式
        return this;
    }

    /**
     * 给指定viewId的ImageView控件设置图片
     * 
     * @param viewId
     * @param imgId
     * @return
     */
    public Convertor setImageResource(int viewId, int resId) {
        ImageView iv = getView(viewId);
        iv.setImageResource(resId);
        return this;
    }

    // PS:
    // 类似setText(),setImageResource()方法,可根据需求自行添加
    // 如Item视图中含有RadioButton控件,那个可以添加setChecked()方法

}

第三步:根据业务需求,新建一个CommonAdapter的子类–ListViewAdapter类,代码如下

/**
 * ListView适配器类
 * 
 * @author HaoG
 *
 */
public class ListViewAdapter3 extends CommonAdapter<ListBean> {

    public ListViewAdapter3(Context context, List<ListBean> beans, int layoutId) {
        super(context, beans, layoutId);
    }
    /**
     * 1、在这里我们可以看到子类中只需要实现其convert()方法即可
     * 2、在Convertor类中,已经封装的相关的接口,在这里直接调用即可
     */
    @Override
    public void convert(Convertor convertor, ListBean bean) {
        convertor.setImageResource(R.id.id_img, bean.getImgId())
                .setText(R.id.id_title, bean.getTitle());
    }
}

3、结语

1、到这里基本就结束了,如果有不太懂的地方,可以去慕课,观看《打造Android万能适配器》
2、这里并不是打广告,我也是Android初学者,在写项目时多个Adapter感到繁琐,刚好碰到这个通用的CommonAdapter,便记录下学习小结,愿与君共进步…
3、感谢《慕课网–打造万能适配器》

 类似资料: