标签:
首先再次感谢 慕课网的技术大牛分享了该课程。
一.传统 ListView 适配器的模式:1. 创建Listview,并为listview 创建item布局2.封装数据 3.为Item布局创建特定的适配器 用于数据展示。(在这过程中,如果某一个ListView 的item中控件过多,控件的生命及调用会导致代码量上升,而如果一个app中有很多个地方需要用到ListView 时,需要分别写多个适配器,会导致很多重复性的操作,为了避免这种情况的发生,让编码更轻松,可参考 慕课网Android万能适配器 的编写。)。
传统Adapter 编码风格如下:
package com.imooc.imooc_adapter; import java.util.List; import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.TextView; public class MyAdapter extends BaseAdapter { private Context context; private List<Bean> mlist; public MyAdapter(Context context, List<Bean> mlist) { super(); this.context = context; this.mlist = mlist; } public List<Bean> getMlist() { return mlist; } public void setMlist(List<Bean> mlist) { this.mlist = mlist; } @Override public int getCount() { return mlist.size(); } @Override public Object getItem(int arg0) { return mlist.get(arg0); } @Override public long getItemId(int arg0) { return arg0; } @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHoler holder =null; if (convertView ==null) { holder = new ViewHoler(); convertView = ((LayoutInflater) context .getSystemService(Context.LAYOUT_INFLATER_SERVICE)) .inflate(R.layout.item, parent,false); holder.name= (TextView) convertView.findViewById(R.id.name); holder.phone = (TextView) convertView.findViewById(R.id.phone); convertView.setTag(holder); }else{ convertView.setTag(holder); } final Bean bean = mlist.get(position); holder.name.setText(bean.getUsername()); holder.phone.setText(bean.getPhone()); return convertView; } class ViewHoler{ TextView name; TextView phone; } }
万能Adapter代码如下:
package com.imooc.imooc_adapter; import java.util.List; import android.content.Context; import com.imooc.util.CommonAdapter; import com.imooc.util.ViewHolder; public class NewAdapter extends CommonAdapter<Bean>{ public NewAdapter(Context context, List<Bean> mdatas,int layoutId) { super(context, mdatas,layoutId); } @Override public void convert(ViewHolder holder, Bean bean) { holder.setText(R.id.phone, bean.getPhone()).setText(R.id.name, bean.getUsername()); } }
由此可见 万能Adapter 可精简的代码量有多少了。
万能适配器 把用户自定义的 ViewHolder 和BaseAdapter 的声明等进行了封装,调用时,需要 CommonAdapter 和ViewHoler 这两个类。
万能适配器 编写逻辑:
1. 封装ViewHolder,将View convertView 解放出来,实现一条代码 即可完成 convertView的实例化:
ViewHolder holder = ViewHolder.get(mcontext, convertView, parent, postion, layoutId);
实现方式:
public class ViewHolder { private SparseArray<View> mViews; private Context mcontext; private View mConvertView; private int mposition; public View getmConvertView() { return mConvertView; } public int getMposition() { return mposition; } public ViewHolder(Context context, ViewGroup parent, int layoutId, int position) { this.mposition = position; this.mViews = new SparseArray<View>(); mConvertView = LayoutInflater.from(context).inflate(layoutId, parent, false); mConvertView.setTag(this); } public static ViewHolder get(Context context, View convertView, ViewGroup parent, int position, int layoutId) { if (convertView == null) { return new ViewHolder(context, parent, layoutId, position); } else { ViewHolder holder = (ViewHolder) convertView.getTag(); holder.mposition = position; return holder; } } public <T extends View> T getView(int viewid) { View view = mViews.get(viewid); if (view == null) { view = mConvertView.findViewById(viewid); mViews.put(viewid, view); } return (T) view; }
此处使用 spareArray 类似于:List<int,Object> 形式的存放,想比较HashMap<int,Object> 来说更加节省时间,提高效率。
创建抽象类 CommonAdapter:
public abstract class CommonAdapter<T> extends BaseAdapter { protected Context mcontext; protected List<T> mDatas; protected LayoutInflater mInlater; private int layoutId; public CommonAdapter(Context context ,List<T> datas,int layoutId) { this.mcontext = context; this.mDatas= datas; this.layoutId = layoutId; mInlater = LayoutInflater.from(context); } public Context getMcontext() { return mcontext; } public void setMcontext(Context mcontext) { this.mcontext = mcontext; } public List<T> getmDatas() { return mDatas; } public void setmDatas(List<T> mDatas) { this.mDatas = mDatas; } @Override public int getCount() { return mDatas.size(); } @Override public T getItem(int arg0) { return mDatas.get(arg0); } @Override public long getItemId(int arg0) { return arg0; } @Override public View getView(int postion, View convertView, ViewGroup parent){ ViewHolder holder = ViewHolder.get(mcontext, convertView, parent, postion, layoutId); convert(holder, getItem(postion)); return holder.getmConvertView(); }; public abstract void convert(ViewHolder holder,T t); }
将 convert 方法 对外开放给开发者,进行简单的赋值操作。
在 自定义的Adapter 中继承 CommonAdapter:
public class NewAdapter extends CommonAdapter<Bean>{ public NewAdapter(Context context, List<Bean> mdatas,int layoutId) { super(context, mdatas,layoutId); } @Override public void convert(ViewHolder holder, Bean bean) { holder.setText(R.id.phone, bean.getPhone()).setText(R.id.name, bean.getUsername()); } }
在MainActivity中初始化自定义Adapter时,可使用:
adapter= new NewAdapter(getApplicationContext(), mList,R.layout.item);
其中,可以在 ViewHolder 封装类中封装 Adapter中对 控件的操作(视个人需求而定)
public ViewHolder setText(int viewId, String text) { TextView tv = getView(viewId); tv.setText(text); return this; } public ViewHolder setImageResource(int viewId,int resId){ ImageView img= getView(viewId); img.setImageResource(resId); return this; }
标签:
原文地址:http://my.oschina.net/leov1/blog/485649