Android通用适配器CommonAdapter
2016-12-07 18:12
459 查看
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、感谢《慕课网–打造万能适配器》
相关文章推荐
- Android——打造万能适配器(CommonAdapter)
- Java泛型应用之打造Android中ListView和GridView万能适配器【CommonAdapter】--超简洁写法
- Android ListView的通用适配器Adapter
- android 一个通用的 适配器 adapter
- Android快速开发工具---通用的适配器Adapter
- 【Android游戏开发二十三】自定义ListView【通用】适配器并实现监听控件!
- Android新浪微博开发(三)主UI的实现:用BaseAdapter做适配器的LsitView
- Android开发之ListView 适配器(Adapter)优化
- android 学习笔记:自定义通用ListView/GridView,实现ListAdapter 类
- 【Android游戏开发二十三】自定义ListView【通用】适配器并实现监听控件!
- Android适配器Adapter学习
- Android ListView 适配器(Adapter)优化
- 【Android游戏开发二十三】自定义ListView【通用】适配器并实现监听控件!
- Android开发之ListView 适配器(Adapter)优化
- 【Android游戏开发二十三】自定义ListView【通用】适配器并实现监听控件!
- Android进阶高手(二)适配器(Adapter)那是必须的
- [转]Android 适配器Adapter的学习
- Android开发之ListView 适配器(Adapter)优化
- Android开发之ListView 适配器(Adapter)优化
- [转]Android 适配器Adapter的学习