RecyclerView優雅的添加Header和Footer

博客轉移到個人站點:

http://www.wangchengmeng.club/2018/02/04/RecyclerView%E4%BC%98%E9%9B%85%E7%9A%84%E6%B7%BB%E5%8A%A0Header%E5%92%8CFooter/

歡迎來吐槽

裝飾模式:再現有類的基礎上,對它進行包裝從而對功能對增強。這裏簡單實現對RecyclerView的Adapter進行裝飾,從而簡單實現對RecylerView增加Header和Footer。



核心思想也是利用getItemViewType()方法,可以返回多種不同類型的View。


不影響原有的功能,使使用起來跟原生的Adapter方式一樣,新建一個WrapperAdapter,繼承自RecyclerView.Adapter<RecyclerView.ViewHolder>




1.聲明一個枚舉:包含三種類型


private enum ITEM_TYPE {
        HEADER, //頭部
        FOOTER, //尾部
        NORMAL//正文
    }
2.構造函數,將使用的adapter作爲參數傳遞進來:



    public WrapperAdapter(RecyclerView.Adapter adapter) {
        mAdapter = adapter;
    }




3.添加-刪除Header和Footer的方法



    public void addFooter(View footerView) {
        mFooterView = footerView;
        notifyDataSetChanged();
    }


    public void removeFooter() {
        if (hasFooter()) {
            mFooterView = null;
            notifyDataSetChanged();
        }
    }


    public void addHeader(View headerView) {
        mHeaderView = headerView;
    }


    private boolean hasHeader() {
        return null != mHeaderView;
    }


    private boolean hasFooter() {
        return null != mFooterView;
    }




4.getItemViewType方法:


@Override
    public int getItemViewType(int position) {
        int count = mAdapter.getItemCount();//獲取除 中間部分的數據條數
        if (hasHeader()) {
            count++; //如果帶了header 那就+1
        }
        if (hasHeader() && position == 0) {
            return ITEM_TYPE.HEADER.ordinal(); //返回header類型
        } else if (hasFooter() && position == count) {
            return ITEM_TYPE.FOOTER.ordinal(); //返回footer類型
        } else {
            return ITEM_TYPE.NORMAL.ordinal(); //返回normal類型
        }
    }




5.獲取數據的數量:

@Override
    public int getItemCount() {
        int count = mAdapter.getItemCount();
        if (hasHeader()) {
            count++;
        }
        if (hasFooter()) {
            count++;
        }
        return count; //獲取數據的數目,要加上對應的帶header和footer的條數
    }




6.返回ViewHolder:


@Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        //根絕不同的類型處理對應的ViewHolder
        if (viewType == ITEM_TYPE.HEADER.ordinal()) {
            return new RecyclerView.ViewHolder(mHeaderView) {
            };
        } else if (viewType == ITEM_TYPE.FOOTER.ordinal()) {
            return new RecyclerView.ViewHolder(mFooterView) {
            };
        } else {
            return mAdapter.onCreateViewHolder(parent, viewType);
        }
    }




7.數據處理的邏輯:


@Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        if (hasHeader() && position == 0) {
            //header的邏輯分離開來,在外部處理
            return;
        }
        int count = mAdapter.getItemCount();
        if (hasHeader()) {
            count++;
        }
        if (hasFooter()) {
            count++;
        }
        if (hasFooter() && position == count - 1) {
            //footer的邏輯分離開來,在外部處理
            return;
        }
        //normal的邏輯還是不變,跟原生的一樣處理,在傳遞進來的adapter中
        if (hasHeader()) {
            mAdapter.onBindViewHolder(holder, position - 1);
        } else {
            mAdapter.onBindViewHolder(holder, position);
        }
    }






一個簡單的添加header和footer就這樣裝飾出來了,對一個現有的類對它進行一個功能爭強,可以利用持有它的引用,原來的操作不變的基礎上添加對應的功能。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章