Android(无需javabean,支持多item type)的RecyclerView万能适配器,解耦从这里做起
(续上篇,这里实现了多item类型的支持。并且支持泛型从定长的5个,到0到9个任选。)
多item类型,这个其实不太好实现。我看了鸿洋的,发现他是只支持单数据的(即就算多item,数据也是共享一个集合),所以我干脆自己实现了一个。
所以该怎么实现呢?不能乱来,要先想好你预期的效果是什么样的。所以我写了一个思路分析,然后就能做了
之后就自己弄了一个抽象类,专门用来盛放不同的item。以两个泛型参数的抽象类举例。
public abstract class MyDelegate2<A,B> implements MyDelegate{ private List<A> aList = null; private List<B> bList = null; public MyDelegate2(List<A> aList, List<B> bList) { this.aList = aList; this.bList = bList; } @Override public void convert(CommonViewHolder holder, int realPosition) { convert(holder, realPosition, aList.get(realPosition), bList.get(realPosition)); } abstract void convert(CommonViewHolder holder, int realPosition, A a, B b); }
interface MyDelegate { void convert(CommonViewHolder holder, int realPosition); }
接下来就简单了,只需要在onBindViewHolder里调用这个接口里公共的方法就可以了。
问题如我思路分析里的一样,怎么知道什么时候该用哪个viewtype呢?
我们需要另外弄一个List<Integer> itemViewtypeList。分别指明,我们的列表里的每一项应该是哪种viewtype,只需要再弄一个map让view type和我们的那个MyDelegate对应起来就可以了。(这里采用的是SparseArray,一样的)我们把布局id作为独一无二的view type。
@Override public int getItemViewType(int position) { if (itemTypeList != null) { return itemTypeList.get(position); } return super.getItemViewType(position); }
所以我们的onCreateViewHolder
@Override public CommonViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View v = inflater.inflate(viewType, null, false); return new CommonViewHolder(v); }
最后看看onBindViewHolder
@Override public void onBindViewHolder(CommonViewHolder holder, int position) { //通过position计算出对应item的position int viewType = itemTypeList.get(position); MyDelegate myDelegate = sparseArray.get(viewType); int realPosition = 0; for (int i = 0; i < position; i ++) { if (itemTypeList.get(i) == viewType) { realPosition ++; } } myDelegate.convert(holder, realPosition); }我们根据position,求出在这个对应种类的item的list中的位置,传过去,就全搞定了。
到这里,我们又不需要javabean,又支持9种泛型,又通用的adapter就搞定了。
看一下使用。
分别是一个泛型的itemViewType,两个泛型的itemViewType
MyDelegate1 myDelegate2_1 = new MyDelegate1<String>(stringList1) { @Override void convert(CommonViewHolder holder, int realPosition, String s) { ViewGroup mRootView = (ViewGroup) holder.itemView; TextView mTextView = (TextView) mRootView.getChildAt(0); mTextView.setText(s); } }; MyDelegate2 myDelegate2_2 = new MyDelegate2<Bitmap, String>(bitmapList2, stringList2) { @Override void convert(CommonViewHolder holder, int realPosition, Bitmap bitmap, String s) { ViewGroup mRootView = (ViewGroup) holder.itemView; ImageView mImageView = (ImageView) mRootView.getChildAt(0); TextView mTextView = (TextView) mRootView.getChildAt(1); mImageView.setImageBitmap(bitmap); mTextView.setText(s); } };
放进sparseArray里
SparseArray<MyDelegate> sparseArray = new SparseArray<>(); sparseArray.put(R.layout.item1, myDelegate2_1); sparseArray.put(R.layout.item2, myDelegate2_2);
new出adapter
CommonAdapter2 adapter = new CommonAdapter2(this, itemList, sparseArray);
搞定
mRv.setLayoutManager(new LinearLayoutManager(this)); mRv.setAdapter(adapter);
全部代码可以去github上看,又简单功能又强,https://github.com/xubinhong/MyRecyclerView4
从今以后既可以光速开发,又可以不怕改需求啦