1. 程式人生 > >RecyclerView新增頭部和尾部

RecyclerView新增頭部和尾部

為RecyclerView新增頭部和底部

第一步1

需要定義一個Adapter,繼承自RecyclerView.Adapter

HeaderAndFooterWrapper<T> extends RecyclerView.Adapter<RecyclerView.ViewHolder>

第二步2

在Adapter的構造方法中傳入一個Adapter物件用於新增除頭部尾部以外的item,並生命所需要用的成員變數

private static final int BASE_ITEM_TYPE_HEADER = 10000;
    private
static final int BASE_ITEM_TYPE_FOOTER = 20000; private SparseArrayCompat<View> mHeaderViews = new SparseArrayCompat<>(); private SparseArrayCompat<View> mFootViews = new SparseArrayCompat<>(); private RecyclerView.Adapter mInnerAdapter; public HeaderAndFooterWrapper
(RecyclerView.Adapter mInnerAdapter) { this.mInnerAdapter = mInnerAdapter; } public boolean isHeaderViewPos(int position){ return position < getHeadersCount(); }

第三步3

需要有新增頭部和尾部的方法,以及判斷當前item是否是頭部和尾部檢視

public boolean isFooterViewPos(int position){
        return
position >= getHeadersCount() + getRealItemCount(); } public void addHeaderView(View view){ mHeaderViews.put(mHeaderViews.size() + BASE_ITEM_TYPE_HEADER,view); } public void addFooterView(View view){ mFootViews.put(mFootViews.size() + BASE_ITEM_TYPE_FOOTER,view); }

第四步4

新增獲取每一種item數量的方法,比如header檢視數量或者footer檢視數量

  private int getRealItemCount() {
        return mInnerAdapter.getItemCount();
    }

    private int getHeadersCount() {
        return mHeaderViews.size();
    }
    private int getFootersCount() {
        return mFootViews.size();
    }
     @Override
    public int getItemCount() {

        return getHeadersCount() + getRealItemCount() + getFootersCount();
    }

第五步5

複寫getItemViewType方法,在該方法中判斷如果是頭部或者尾部檢視就返回其在
private SparseArrayCompat mHeaderViews = new SparseArrayCompat<>();
private SparseArrayCompat mFootViews = new SparseArrayCompat<>();中的下標,以便獲取

@Override
    public int getItemViewType(int position) {
        if(isHeaderViewPos(position)){
            return mHeaderViews.keyAt(position);
        }else if(isFooterViewPos(position)){
            //如果當前是footerview 就計算出其在footerViews中的下標位置
            return mFootViews.keyAt(position - getHeadersCount() - getRealItemCount());
        }
        return mInnerAdapter.getItemViewType(position - getHeadersCount());
    }

第六步6

複寫onCreateViewHolder方法,和onBindViewHolder方法

 @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        if(mHeaderViews.get(viewType) != null){
            ViewHolder vh = ViewHolder.crateViewHolder(parent.getContext(),
                    mHeaderViews.get(viewType));
            return vh;
        }else if(mFootViews.get(viewType) != null){
            ViewHolder vh = ViewHolder.crateViewHolder(parent.getContext(),
                    mFootViews.get(viewType));
            return vh;
        }

        return mInnerAdapter.onCreateViewHolder(parent,viewType);
    }


    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        if(isHeaderViewPos(position)){
            return;
        }else if(isFooterViewPos(position)){
            return;
        }
        mInnerAdapter.onBindViewHolder(holder,position - getHeadersCount());
    }

到此已經完成了新增頭部的基本程式碼,但是如果需要在宮格佈局下head依然佔據一行的話需要新增一下程式碼

複寫onAttachedToRecyclerView方法,在該方法中判斷是否是GridLayoutManger,getSpanCount意思在構造GridLayoutManger的時候所傳入的每行item數量,返回值的意思就是代表當前view所需要佔據多少個item

 @Override
    public void onAttachedToRecyclerView(RecyclerView recyclerView) {
        mInnerAdapter.onAttachedToRecyclerView(recyclerView);
        final RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();
        if(layoutManager instanceof GridLayoutManager){

            final GridLayoutManager gridLayoutManager = (GridLayoutManager) layoutManager;
            gridLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
                @Override
                public int getSpanSize(int position) {
                    int viewType = getItemViewType(position);
                    if(mHeaderViews.get(viewType) != null){
                        return ((GridLayoutManager) layoutManager).getSpanCount();
                    }else if(mFootViews.get(viewType) != null){
                        return ((GridLayoutManager) layoutManager).getSpanCount();
                    }
                    return 1;
                }
            });
            gridLayoutManager.setSpanCount(gridLayoutManager.getSpanCount());
        }
    }