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

靜下來想想這樣的效果并不難實現(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, ContentHolder 和 FooterHolder,他們的實現(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 就可以了。