給RecyclerView增加頭部布局本身不存在什麼難度,按照我們正常的流程,寫一個符合我們業務邏輯的頭部布局的ViewHolder,然後在getItemViewType()裡通過position傳回一個表示頭部布局ViewHolder的Type類型,然後在onCreateItemViewHolder(ViewGroup parent, int viewType)裡通過viewType來初始化return我們不同的ViewHolder。
public void addHeader(View headerView) {
if (!headerViews.contains(headerView)) {
headerViews.add(headerView);
//當然這裡可以使用notifyItemChanged(int position)去優化
notifyDataSetChanged();
}
}
給Header設定一個合适的Type,比如:
public static final int VIEW_TYPE_HEADER_OFFSET = Integer.MIN_VALUE;
接下來就是getItemViewType()方法的處理了。
@Override
public int getItemViewType(int position) {
if (!headerViews.isEmpty() && position < headerViews.size()) {
return VIEW_TYPE_HEADER_OFFSET + position;
}
//計算我們正常資料的position,也就是減去Header的List的size的數量即可
if (!headerViews.isEmpty()) {
position -= headerViews.size();
}
//adapter就是我們在構造方法裡傳進來的RecyclerView.Adapter
if (adapter != null && position < adapter.getItemCount()) {
return adapter.getItemViewType(position);
}
}
return了viewType,那麼我們就要處理onCreateViewHolder()方法了。
public static boolean isHeaderView(int viewType) {
return viewType < VIEW_TYPE_HEADER_OFFSET;
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if (isHeaderView(viewType)) {
return new HeaderViewHolder(headerViews.get(viewType - VIEW_TYPE_HEADER_OFFSET));
}
return adapter.onCreateViewHolder(parent, viewType);
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
int viewType = getItemViewType(position);
//這裡直接return的原因,我們這裡不做對Header的處理,交由外部。
if (isHeaderView(viewType)) {
return;
}
position -= headerViews.size();
adapter.onBindViewHolder(holder, position);
}