學習了 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 的存在财著,如果還是設置成get(position)
會出現(xiàn)數(shù)組下標越界錯誤联四,這里設置成 get(position - mHeaderCount))
也是為了控制添加和移除 Header
的。
好了撑教,相信如果以上效果你能實現(xiàn)朝墩,那么你也就能實現(xiàn)我們一開始說的 間隔 ItemView
不同布局的問題了,只需要在 getItemViewType()
方法中進行奇偶判斷伟姐,返回不同的 viewType
就可以了收苏。