RecyclerView 添加 Footer and Header

學(xué)習(xí)了 RecyclerView 的使用后,發(fā)現(xiàn) 每個顯示 ItemView 的高度寬度,以及款式都是一樣的,很是單調(diào),于是就想著如果能兩種不同的 ItemView 間隔著顯示就好了,或者說如果頭部和底部能區(qū)別于 ItemView就好了。

首先,看看添加 頭部和底部的效果圖

20160511142236439.png

靜下來想想這樣的效果并不難實現(xiàn),在 RecyclerView 中我們的視圖都是通過RecyclerView.ViewHolder來給我提供子視圖的,而這個 ViewHolder 的創(chuàng)建是由 RecyclerView.Adapter 中的onCreateViewHolder() 方法控制的,來仔細看看這個方法

public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) 

咦,這個 viewType是什么東西???實際上這個 viewType是我們可以改動的,通過 getItemViewType() 這個方法,這也就意味著,我們可以控制 ViewHolder 的創(chuàng)建,那么這樣這個效果就容易實現(xiàn)了。

首先,我們創(chuàng)建三個 RecyclerView.ViewHolder,分別命名為 HeaderHolder, ContentHolderFooterHolder,他們的實現(xiàn)實際上是一樣的,除了 TextView 的命名不一樣。來看看這三個類

public class HeaderHolder extends RecyclerView.ViewHolder {

    public TextView mHeaderText;

    public HeaderHolder(View itemView) {
        super(itemView);
        mHeaderText = (TextView) itemView.findViewById(R.id.tv_header);

    }
}

public class ContentHolder extends RecyclerView.ViewHolder {
    public TextView mContentText;

    public ContentHolder(View itemView) {
        super(itemView);
        mContentText = (TextView) itemView.findViewById(R.id.tv_content);
    }
}

public class FooterHolder extends RecyclerView.ViewHolder {

    public TextView mFooterText;

    public FooterHolder(View itemView) {
        super(itemView);
        mFooterText = (TextView) itemView.findViewById(R.id.tv_footer);
    }
}

下面就是 RecyclerView.Adapter 的實現(xiàn)了,先來看看具體代碼

public class CustomAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
    public static final int HEADER_ITEM = 0;
    public static final int CONTENT_ITEM = 1;
    public static final int FOOTER_ITEM = 2;
    public List<String> mDatas;
    private Context mContext;
    private LayoutInflater mInflater;

    private int mHeaderCount = 1;
    private int mFooterCount = 1;

    private String mHeaderText = "Header";
    private String mFooterText = "Footer";

    public CustomAdapter(Context context, List<String> datas) {
        mContext = context;
        mDatas = datas;
        mInflater = LayoutInflater.from(context);
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        if (viewType == HEADER_ITEM) {
            return new HeaderHolder(mInflater.inflate(R.layout.recycler_header, parent, false));
        } else if (viewType == CONTENT_ITEM) {
            return new ContentHolder(mInflater.inflate(R.layout.recycler_content, parent, false));
        } else {
            return new FooterHolder(mInflater.inflate(R.layout.recycler_footer, parent, false));
        }
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        if (holder instanceof HeaderHolder) {
            ((HeaderHolder) holder).mHeaderText.setText(mHeaderText);
        } else if (holder instanceof FooterHolder) {
            ((FooterHolder) holder).mFooterText.setText(mFooterText);
        } else if (holder instanceof ContentHolder) {
            ((ContentHolder) holder).mContentText.setText(mDatas.get(position - mHeaderCount));
        }
    }

    @Override
    public int getItemViewType(int position) {

        int count = mDatas.size();
        if (mHeaderCount != 0 && position < mHeaderCount) return HEADER_ITEM;
        else if (mFooterCount != 0 && position >= (mHeaderCount + count)) return FOOTER_ITEM;
        else return CONTENT_ITEM;
    }

    @Override
    public int getItemCount() {
        return mDatas.size() + mHeaderCount + mFooterCount;
    }

    public void setFooterText(String footerText) {
        mFooterText = footerText;
    }

    public void setHeaderText(String headerText) {
        mHeaderText = headerText;
    }

    public void removeFooter() {
        mFooterCount = 0;
    }

    public void removeHeader() {
        mHeaderCount = 0;
    }
}

相信有了前面的分析,讓你看懂以上代碼并不困難,但是需要注意的是

if (holder instanceof ContentHolder) {
            ((ContentHolder) holder).mContentText.setText(mDatas.get(position - mHeaderCount));
}

注意這段代碼中的 get方法,不是 get(position) ,因為有了 mHeaderCount 的存在,如果還是設(shè)置成get(position) 會出現(xiàn)數(shù)組下標越界錯誤,這里設(shè)置成 get(position - mHeaderCount)) 也是為了控制添加和移除 Header 的。

好了,相信如果以上效果你能實現(xiàn),那么你也就能實現(xiàn)我們一開始說的 間隔 ItemView不同布局的問題了,只需要在 getItemViewType() 方法中進行奇偶判斷,返回不同的 viewType 就可以了。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容