原文 http://www.jianshu.com/p/cef7b2808335
如果你是做 android 开发的一个组件是你一定会常常使用到的,没错就是 ListView,
对于 ListView 的使用,他有两个重点的部分,一个是下拉刷新和加载更多,这个今天我们不讲,另外一个是 BaseAdapter 的使用,这个是今天的主角,BaseAdapter 中又有 ViewHolder 模式来实现缓存视图
继承BaseAdapter类,实现以下几个方法
getCount() ->int 返回的是 List的个数 getView(int, View, ViewGroup)->View 返回显示的视图 getItemId(int position) ->long返回position位置的 id getItem(int position)->Object 返回position位置的 item
现在我们在这个基础上,继承 BaseAdapter 实现几个方法.
MBaseAdapter.class
public abstract class MBaseAdapter extends BaseAdapter { public LayoutInflater inflater; public Context context; public List<?> list; public MBaseAdapter(Context context, List<?> list) { this.context = context; this.list = list; this.inflater = LayoutInflater.from(context); } public MBaseAdapter(LayoutInflater inflater, List<?> list) { this.context = inflater.getContext(); this.list = list; this.inflater = inflater; } @Override public int getCount() { return list.size(); } @Override public Object getItem(int position) { return list.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { return getView33(position, convertView, parent); } /** * 与BaseAdapter 中的getView() 一样 * * @param position * @param convertView * @param parent * @return */ public abstract View getView33(int position, View convertView, ViewGroup parent); }
为了实现 ViewHodler 缓存我写了这个工具类
ViewHolderUtils.class
public class ViewHolderUtils { /** * 得到视图为 view 的 viewHodler * @param view * @return */ public ViewHolder get(View view) { ViewHolder viewHolder = (ViewHolder) view.getTag(); if (viewHolder == null) { viewHolder = new ViewHolder(view); view.setTag(viewHolder); } return viewHolder; } /** * viewhodler 存储 view的子 view 的索引 * @author zzz40500 * */ public class ViewHolder { private SparseArray<View> viewHolder; private View view; public ViewHolder(View view) { this.view = view; viewHolder = new SparseArray<View>(); } public <T extends View> T get(int id) { View childView = viewHolder.get(id); if (childView == null) { childView = view.findViewById(id); viewHolder.put(id, childView); } return (T) childView; } /** * 得到 view 下 id 为 id 的TextView 这里没有做类型的判断所以你要保证 id 为 id 的控件确实为 TextView类型 * @param id * @return */ public TextView getTextView(int id) { return get(id); } /** * 直接设置文字 * @param id * @param text */ public void setText(int id,String text){ getTextView(id).setText(text); } public ImageView getImageView(int id) { return get(id); } } }
现在结合上面两个类,我们可是实现了更简单的 adapter 写法
AutoAdapter.class
public abstract class AutoAdapter extends MBaseAdapter{ /** * item 的布局文件 */ private int layoutID; /** * 这是一个生产 ViewHolder的工具类 */ private ViewHolderUtils vh; public AutoAdapter(Context context, List<?> list, int layoutID) { super(context, list); this.layoutID = layoutID; vh = new ViewHolderUtils(); } @Override public View getView33(int position, View convertView, ViewGroup parent) { if (convertView == null) { convertView = inflater.inflate(layoutID, parent, false); } getView33(position, convertView, vh.get(convertView)); return convertView; } /** * 通过暴露这个方法,通过操作vh实现将数据的绑定在视图上 * @param position * @param v * @param vh */ public abstract void getView33(int position, View v, ViewHolderUtils.ViewHolder vh); }
重点来了:
我们现在有一个适配器要写,怎么写呢,只要继承AutoAdapter,
我们只要实现了两个方法:getView33和它自身的构造方法,他就可以快速实现了适配器的编写,并且这个适配器是 Viewhodler 的形式.
例子:
public class DemoAdapter extends AutoAdapter { public DemoAdapter(Context context, List<?> list) { /** * 这里的 LayoutID 确定 ListView item 的布局资源文件. */ super(context, list, R.layout.item); } /** * 将数据绑定在视图上 */ @Override public void getView33(int position, View v, ViewHolder vh) { Entity item=(Entity) list.get(position); vh.getTextView(R.id.name).setText(item.getName()); vh.getTextView(R.id.age).setText(item.getAge()); vh.setText(R.id.height,item.getHeight()); } }
在 Activity 中的使用:
BaseAdapter adapter=new DemoAdapter(this, dateA); listView.setAdapter(adapter);
为了方便大家,提供了 eclipse 版本的源码
源码放在 csdn中:http://download.csdn.net/detail/u010637692/8351645