1. 程式人生 > >Android(無需javabean)的RecyclerView萬能介面卡,解耦從這裡做起

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, int 
position, 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