android之adapter的抽象与提炼
2016-03-22 13:54
435 查看
在网上关于adpter的文章太多了,大多都是对adapter中的getView()方法如何优化之类的,然后逐渐形成一种公认的adatper模板,大致如下:
其实主要做法就是把以前的内部类ViewHolder提炼成一个公共的ViewHolder,这样就可以复用了,代码如下:
ViewHolder抽出来之后,来看下adapter怎么实现
这里将之前子view的实现用setView这个抽像方法来实现了,这样就可以动态的添加需要的view。
好了,所有的东西都提出来了,现在来看看怎么去继承这个新的adapter
ok,这个adapter到此为止,以后就可以像这样简单的去写每个adapter了,如果有什么不好的地方,望大神们指出!
另,这其中参考了慕课网里面的课程
public class ESAdapter extends BaseAdapter { @Override public View getView(int position, View convertView, ViewGroup parent) { if (convertView == null) { //TODO ... } //TODO ... } class ViewHolder{ //TODO ... } }主要是在getView()里面对缓存的converView判断了再做处理,然后再添加一个内部类来管理item模板里同的view。当然,这样做没什么问题,今天要说的并不是这个,而是对这个adapter做进一步的提炼。试想,能不能把这个ViewHolder抽象出来,否则每建一个adapter都必须加上一个内部类;其次,getView()方法里面的结构也是一模一样,是否也可以把getView()进一步提炼,当然,这两者是有关联的,既然想到这些可以让代码更简洁的问题,那今天就对这种模板化的adapter做一下升级了,哈哈~
其实主要做法就是把以前的内部类ViewHolder提炼成一个公共的ViewHolder,这样就可以复用了,代码如下:
/** * used in adapter * * @author levi.li * */ public class ViewHolder { private SparseArray<View> mViews; private int mPosition; private View mConvertView; private ViewHolder(Context context, ViewGroup parent, int layoutId, int position) { this.mPosition = position; this.mViews = new SparseArray<View>(); this.mConvertView = LayoutInflater.from(context).inflate(layoutId, parent, false); this.mConvertView.setTag(this); } public static ViewHolder get(Context context, View convertView, ViewGroup parent, int layoutId, int position) { if (convertView == null) { return new ViewHolder(context, parent, layoutId, position); } ViewHolder holder = (ViewHolder) convertView.getTag(); holder.mPosition = position; return holder; } public int getPosition() { return mPosition; } /** * get view by viewId * * @param viewId * @return */ @SuppressWarnings("unchecked") public <T extends View> T getView(int viewId) { View v = mViews.get(viewId); if (v == null) { v = mConvertView.findViewById(viewId); mViews.put(viewId, v); } return (T) v; } /** * set value to TextView * * @param id * @param text * @return */ public ViewHolder setTextView(int id, String text) { ((TextView) getView(id)).setText(text); return this; } /** * set value to CheckBox * * @param id * @param b * @return */ public ViewHolder setCheckBox(int id, boolean b) { ((CheckBox) getView(id)).setChecked(b); return this; } public View getConvertView() { return this.mConvertView; } }对于get(),这里主要是把原先getView()里面对convertView的判断抽出来,对ViewHolder内部类的抽象,主要体现在getView和set方法上,并将这些view存在SparseArray中;
ViewHolder抽出来之后,来看下adapter怎么实现
/** * base adapter, used as ListView's adapter * * @author levi.li * */ public abstract class ESBaseAdapter<T> extends BaseAdapter { protected Context mContext; protected List<T> mData; protected int mLayoutId; public ESBaseAdapter(Context context, List<T> listData, int layoutId) { this.mContext = context; this.mData = listData; this.mLayoutId = layoutId; } @Override public int getCount() { return mData.size(); } @Override public T getItem(int position) { return mData.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder = ViewHolder.get(this.mContext, convertView, parent, this.mLayoutId, position); setViews(holder, getItem(position)); return holder.getConvertView(); } /** * set value to View . this method must override in child adapter class * * @param holder * @param t */ public abstract void setViews(ViewHolder holder, T t);
这里将之前子view的实现用setView这个抽像方法来实现了,这样就可以动态的添加需要的view。
好了,所有的东西都提出来了,现在来看看怎么去继承这个新的adapter
public class TestAdapter extends ESBaseAdapter<TestModel<String>> { public TestAdapter(Context context, List<TestModel<String>> listData) { super(context, listData, R.layout.test_pulltorefresh_list_item); } @Override public void setViews(ViewHolder holder, final TestModel<String> model) { holder.setTextView(R.id.test_pulltorefresh_item_text, model.testDescription); final CheckBox cb = holder.getView(R.id.test_pulltorefresh_item_check); cb.setChecked(model.testFlag); cb.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { model.testFlag = cb.isChecked(); } }); } }很简单了,里面只需要重写setView就好了。
ok,这个adapter到此为止,以后就可以像这样简单的去写每个adapter了,如果有什么不好的地方,望大神们指出!
另,这其中参考了慕课网里面的课程
相关文章推荐
- Android 之TextView文本折叠查看显示更多效果
- Android之SAX解析XML
- Android项目:手机安全卫士(15)—— 获取手机安装应用与存储空间
- Android Activity生命周期理解
- Android常见对话框
- android 加载图片
- android 源码编译
- android 中遥控器键值的添加和修改
- Android NDK环境搭建
- Android frameworks层按键处理流程
- android 图标解决方案汇总
- 获取Android SHA1与Package
- android launcher3 home页简易分析
- Android之CookieStore的持久化
- Android的multidex使用及优化
- Android新手入门2016(11)--非阻塞对话框AlertDialog
- Android开发案例 – 在AbsListView中使用倒计时
- Android 获取字符串高度与宽度
- C开发、Android专业人员
- android的消息处理机制(图+源码分析)——Looper,Handler,Message