其中的关键点在于通过SparseArray<View>存储item view的控件,getView(int id)的功能就是通过id获得对应的View(首先在mViews中查询是否存在,如果没有,那么findViewById()并放入mViews中,避免下次再执行findViewById())。
QuickAdapter的实现如下:
public abstract class QuickAdapter<T> extends RecyclerView.Adapter<QuickAdapter.VH>{ private List<T> mDatas; public QuickAdapter(List<T> datas){ this.mDatas = datas; } public abstract int getLayoutId(int viewType); @Override public VH onCreateViewHolder(ViewGroup parent, int viewType) { return VH.get(parent,getLayoutId(viewType)); } @Override public void onBindViewHolder(VH holder, int position) { convert(holder, mDatas.get(position), position); } @Override public int getItemCount() { return mDatas.size(); } public abstract void convert(VH holder, T data, int position); static class VH extends RecyclerView.ViewHolder{ private SparseArray<View> mViews; private View mConvertView; private VH(View v){ super(v); mConvertView = v; mViews = new SparseArray<>(); } public static VH get(ViewGroup parent, int layoutId){ View convertView = LayoutInflater.from(parent.getContext()).inflate(layoutId, parent, false); return new VH(convertView); } public <T extends View> T getView(int id){ View v = mViews.get(id); if(v == null){ v = mConvertView.findViewById(id); mViews.put(id, v); } return (T)v; } public void setText(int id, String value){ TextView view = getView(id); view.setText(value); } } }其中:
getLayoutId(int viewType)是根据viewType返回布局ID。
convert()做具体的bind操作。
就这样,万能适配器实现完成了。
通过万能适配器能通过以下方式快捷地创建一个Adapter:
mAdapter = new QuickAdapter<String>(data) { @Override public int getLayoutId(int viewType) { return R.layout.item; } @Override public void convert(VH holder, String data, int position) { holder.setText(R.id.text, data); //holder.itemView.setOnClickListener(); 此处还可以添加点击事件 } };是不是很方便。当然复杂情况也可以轻松解决。
mAdapter = new QuickAdapter<Model>(data) { @Override public int getLayoutId(int viewType) { switch(viewType){ case TYPE_1: return R.layout.item_1; case TYPE_2: return R.layout.item_2; } } @Override public int getItemViewType(int position) { if(position % 2 == 0){ return TYPE_1; } else{ return TYPE_2; } } @Override public void convert(VH holder, Model data, int position) { int type = getItemViewType(position); switch(type){ case TYPE_1: holder.setText(R.id.text, data.text); break; case TYPE_2: holder.setImage(R.id.image, data.image); break; } } }; Item Decoration间隔样式