因为懒惰,所以造就各种便捷的工具类。 --来自懒惰的猿
android写了很多的listview也写了很多adapter,每个适配器都要实现它的方法,每个适配器里面还要加一个内部类viewHolder去承载它的view然后实现复用,简直就是浪费时间,身为一个懒惰的程序员完全不能忍,所以CommonAdapter应用而生。(talk is cheap,先上代码在废话)
/** * @Author: malen(qzmmdsl@sina.cn). * @Detail: CommonAdapter * @Motto: Never Give Up !!! */ public abstract class CommonAdapter<T> extends BaseAdapter { private List<T> mDataList; private Activity context; private int layoutId; public OnItemClickListener itemClickListener; public CommonAdapter(Activity context, List<T> mDataList, int layoutId) { this.mDataList = mDataList; this.context = context; this.layoutId = layoutId; } @Override public int getCount() { return null == mDataList ? 0 : mDataList.size(); } @Override public T getItem(int position) { return mDataList.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(final int position, View convertView, ViewGroup parent) { final CommonViewHolder commonViewHolder = CommonViewHolder.get(context, convertView, parent, layoutId); View view = commonViewHolder.getConvertView(); resetView(position, commonViewHolder, getItem(position)); view.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (itemClickListener != null) { itemClickListener.onItemClick(getItem(position), R.id.parentId, position); } } }); return view; } public abstract void resetView(int position, CommonViewHolder viewHolder, T item); public void updateData(List<T> data) { this.mDataList = data; notifyDataSetChanged(); } public void setOnitemClickListenr(OnItemClickListener<T> onitemClickListenr) { this.itemClickListener = onitemClickListenr; } public List<T> getListData() { return mDataList; } public Activity getContext() { return context; } }
抽象化一个CommonAdapter类,利用泛型传入数据源,实现BaseAdapter的四个抽象方法,这样继承CommonAdapter时候就不用在实现这些方法,如果有定制化需求也可以重写这些方法,CommonAdapter这里新添加的抽象方法resetView(),是以便继承类可以进行view跟数据的绑定操作。
public interface OnItemClickListener <T> { /** * 点击事件分发 * @param item * @param viewId * @param position */ void onItemClick(T item,int viewId,int position); }
我们的CommonAdapter还实现了item的点击回调事件,可以针对item的不同viewid进行回调事件分发,这里的parentId是事先定义好的一个整体item的id,这样就直接可以在Activity里面直接进行回调处理。 这里还有一个莫名其妙的CommonViewHolder,其实就是一个万能ViewHolder。
public class CommonViewHolder { private SparseArray<View> mViews; private View mConvertView; public CommonViewHolder(Context context, ViewGroup parent, int layoutId) { this.mViews = new SparseArray<>(); mConvertView = LayoutInflater.from(context).inflate(layoutId, parent, false); mConvertView.setTag(this); } public static CommonViewHolder get(Context context, View mConvertView, ViewGroup viewGroup, int layoutId) { if (mConvertView == null) { return new CommonViewHolder(context, viewGroup, layoutId); } return (CommonViewHolder) mConvertView.getTag(); } public View getConvertView() { return mConvertView; } public <T extends View> T getView(int viewId, Class<T> tClass) { View view = mViews.get(viewId); if (view == null) { view = mConvertView.findViewById(viewId); mViews.put(viewId, view); } return (T) view; } 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; } }
首先说一下SparseArray,SparseArray是Android里为<Interger,Object>这样的Hashmap而专门写的类,目的是提高内存效率,其核心是折半查找函数(binarySearch),这里把每个view都存放在SparseArray里,不用每次都去findview,mConvertView也进行了复用处理,这些操作都是为了提高内存效率以及让listview滚动的更流畅。
示例如下:
public class Adapter extends CommonAdapter<String> {//传入任意数据源类型 public Adapter(Activity context, List<String> mDataList, int layoutId) { super(context, mDataList, layoutId); } @Override public void resetView(int position, CommonViewHolder viewHolder, String item) { //这里写入你的item的view逻辑处理和数据绑定 //提供两种getview方法 viewHolder.getView(R.id.textView, TextView.class).setText(""); TextView textView=viewHolder.getView(R.id.textView); } }感谢阅读!