Android(無需javabean)的RecyclerView萬能介面卡,解耦從這裡做起
先介紹下為什麼這麼做,因為RecyclerView需要一個javabean,同時呢,對於整個系統中的一個物件,也需要建造一個javabean。但是很明顯,RecyclerView中的那個bean顯然是整個系統中那個物件javabean的子集。所以我覺得不應該專門為RecyclerView設定一個bean,你想要給他什麼資料,多傳幾個集合不就好了?為什麼一定要並在一個集合裡?所以我認為,javabean反而是最容易忽視,也是最高的耦合度的體現。
本來的List---List<XxxxBean>
現在的List---List<String> List<Bitmap> List<...>
(我覺得下面那種才是健康,更容易維護的形式!!!使用者要改需求,增加一個List就可以和一行繫結的程式碼就可以!!!)
先看一下我的除了通用的ViewHolder和通用的Adapter之外的所有程式碼
CommonAdapter adapter = new CommonAdapter<String, Bitmap, String, String, String>(this,R.layout.item, stringList, bitmapList, null, null, null) { @Override protected void convert(CommonViewHolder holder, intposition, String s, Bitmap bitmap, String s2, String s3, String s4) { ((TextView)((ViewGroup)holder.getItemView()).getChildAt(0)).setText(s); ((ImageView)((ViewGroup)holder.getItemView()).getChildAt(1)).setImageBitmap(bitmap); } }; mRv.setAdapter(adapter); mRv.setLayoutManager(new LinearLayoutManager(this));
這裡我就使用了兩個資料型別,一個String,一個是Bitmap,後面的泛型不得不指定,就瞎指定了幾個(也可以像rxjava寫9個類,這樣就可以動態指定泛型個數了)。整個流程下來,就是舒服二字!
假如說這是一個聊天系統,使用者一開始說,他要的是String型別的,因為只發文字就可以了 。但是他心思變的很快,說,我想要一個通用的訊息型別,比如是MyMessage型別,所以這個時候,你得到bean裡去改,得到adapter裡去改,如果你的業務已經做了很多了,大部分的業務都要改!這裡就可以規避一下。只需要List<String>變成List<MyMessage>就可以了,舒服。
看一下抽象出來的通用的ViewHolder和Adapter,思路很簡單,一看就懂:
ViewHolder
public class CommonViewHolder extends RecyclerView.ViewHolder { private View itemView = null; private SparseArray<View> mViewSparseArray;//類似map,內部結構還沒來得及看 public CommonViewHolder(View itemView) { super(itemView); mViewSparseArray = new SparseArray<>(); this.itemView = itemView; } public View holdAndGetView(int viewId) { View v = mViewSparseArray.get(viewId); if (v == null) { v = itemView.findViewById(viewId); } return v; } public View getItemView() { return itemView; } }其實我的這個holdAndGetView方法都沒用到,我的item佈局也沒設定id,直接通過getChildAt的形式去取了,很舒服。(如果客官狠一點,完全可以改造一下,讓item佈局都不要了,直接new個常用的根佈局出來,然後設定佈局引數往裡面加子控制元件就可以。)
CommonAdapter
public abstract class CommonAdapter<A, B, C, D, E> extends RecyclerView.Adapter<CommonViewHolder> { private Context context = null; private LayoutInflater inflater = null; private int layoutId = 0; private List<A> aList = null; private List<B> bList = null; private List<C> cList = null; private List<D> dList = null; private List<E> eList = null; // TODO: 2017/12/31 POJO類其實就是一種耦合 改動起來 非常非常非常不方便 //make sure list size is equals public CommonAdapter(Context context, int layoutId, List<A> aList, List<B> bList, List<C> cList, List<D> dList, List<E> eList) { this.context = context; this.inflater = LayoutInflater.from(context); this.layoutId = layoutId; this.aList = aList != null ? aList : null; this.bList = bList != null ? bList : null; this.cList = cList != null ? cList : null; this.dList = dList != null ? dList : null; this.eList = eList != null ? eList : null; } // TODO: 2017/12/31 先只搞單item type的 @Override public CommonViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View v = inflater.inflate(layoutId, parent, false); return new CommonViewHolder(v); } @Override public void onBindViewHolder(CommonViewHolder holder, int position) { A a = aList != null ? aList.get(position) : null; B b = bList != null ? bList.get(position) : null; C c = cList != null ? cList.get(position) : null; D d = dList != null ? dList.get(position) : null; E e = eList != null ? eList.get(position) : null; convert(holder, position, a, b, c, d, e); } protected abstract void convert(CommonViewHolder holder, int position, A a, B b, C c, D d, E e); @Override public int getItemCount() { return aList.size(); } }
最後講一下,每個安卓開發者,都不應該使用別人封裝的RecyclerView,而是應該有自己的一RrecyclerView,你想擴充功能的時候,你是改不了別人的gradle的。只有自己的,改起來才最方便,每個人對於RecyclerView的業務需求都是不一樣的(不僅僅是list,還有下拉重新整理等等各式各樣花裡胡哨的操作)。有了專門適合自己的一套,其開發效率和可維護重用性,可以說是正常人的數倍,而且就算出了錯,自己也非常容易盤查。
github地址:(接下來還會新增多item佈局等功能)https://github.com/xubinhong/MyRecyclerView4