package com.moral.andbrickslib.baseadapter.headandfooter;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.StaggeredGridLayoutManager;
import android.view.View;
import android.view.ViewGroup;
import java.util.ArrayList;
/**
* Created by cundong on 2015/10/9.
*
* RecyclerView.Adapter with Header and Footer
*/
public class HeaderAndFooterRecyclerViewAdapter extends RecyclerView.Adapter {
private static final int TYPE_HEADER_VIEW = Integer.MIN_VALUE;
private static final int TYPE_FOOTER_VIEW = Integer.MIN_VALUE + 1;
/**
* RecyclerView使用的,真正的Adapter
*/
private RecyclerView.Adapter mInnerAdapter;
private ArrayList mHeaderViews = new ArrayList<>();
private ArrayList mFooterViews = new ArrayList<>();
private RecyclerView.AdapterDataObserver mDataObserver = new RecyclerView.AdapterDataObserver() {
@Override
public void onChanged() {
super.onChanged();
notifyDataSetChanged();
}
@Override
public void onItemRangeChanged(int positionStart, int itemCount) {
super.onItemRangeChanged(positionStart, itemCount);
notifyItemRangeChanged(positionStart + getHeaderViewsCount(), itemCount);
}
@Override
public void onItemRangeInserted(int positionStart, int itemCount) {
super.onItemRangeInserted(positionStart, itemCount);
notifyItemRangeInserted(positionStart + getHeaderViewsCount(), itemCount);
}
@Override
public void onItemRangeRemoved(int positionStart, int itemCount) {
super.onItemRangeRemoved(positionStart, itemCount);
notifyItemRangeRemoved(positionStart + getHeaderViewsCount(), itemCount);
}
@Override
public void onItemRangeMoved(int fromPosition, int toPosition, int itemCount) {
super.onItemRangeMoved(fromPosition, toPosition, itemCount);
int headerViewsCountCount = getHeaderViewsCount();
notifyItemRangeChanged(fromPosition + headerViewsCountCount, toPosition + headerViewsCountCount + itemCount);
}
};
public HeaderAndFooterRecyclerViewAdapter() {
}
public HeaderAndFooterRecyclerViewAdapter(RecyclerView.Adapter innerAdapter) {
setAdapter(innerAdapter);
}
/**
* 设置adapter
* @param adapter
*/
public void setAdapter(RecyclerView.Adapter adapter) {
if (adapter != null) {
if (!(adapter instanceof RecyclerView.Adapter))
throw new RuntimeException("your adapter must be a RecyclerView.Adapter");
}
if (mInnerAdapter != null) {
notifyItemRangeRemoved(getHeaderViewsCount(), mInnerAdapter.getItemCount());
mInnerAdapter.unregisterAdapterDataObserver(mDataObserver);
}
this.mInnerAdapter = adapter;
mInnerAdapter.registerAdapterDataObserver(mDataObserver);
notifyItemRangeInserted(getHeaderViewsCount(), mInnerAdapter.getItemCount());
}
public RecyclerView.Adapter getInnerAdapter() {
return mInnerAdapter;
}
public void addHeaderView(View header) {
if (header == null) {
throw new RuntimeException("header is null");
}
if(mHeaderViews.size()!=0){
return;
}
mHeaderViews.add(header);
this.notifyDataSetChanged();
}
public void addFooterView(View footer) {
if (footer == null) {
throw new RuntimeException("footer is null");
}
if(mFooterViews.size()!=0){
return;
}
mFooterViews.add(footer);
this.notifyDataSetChanged();
}
/**
* 返回第一个FoView
* @return
*/
public View getFooterView() {
return getFooterViewsCount()>0 ? mFooterViews.get(0) : null;
}
/**
* 返回第一个HeaderView
* @return
*/
public View getHeaderView() {
return getHeaderViewsCount()>0 ? mHeaderViews.get(0) : null;
}
public void removeHeaderView(View view) {
mHeaderViews.remove(view);
this.notifyDataSetChanged();
}
public void removeFooterView(View view) {
mFooterViews.remove(view);
this.notifyDataSetChanged();
}
public int getHeaderViewsCount() {
return mHeaderViews.size();
}
public int getFooterViewsCount() {
return mFooterViews.size();
}
public boolean isHeader(int position) {
return getHeaderViewsCount() > 0 && position == 0;
}
public boolean isFooter(int position) {
int lastPosition = getItemCount() - 1;
return getFooterViewsCount() > 0 && position == lastPosition;
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
int headerViewsCountCount = getHeaderViewsCount();
if (viewType < TYPE_HEADER_VIEW + headerViewsCountCount) {
return new ViewHolder(mHeaderViews.get(viewType - TYPE_HEADER_VIEW));
} else if (viewType >= TYPE_FOOTER_VIEW && viewType < Integer.MAX_VALUE / 2) {
return new ViewHolder(mFooterViews.get(viewType - TYPE_FOOTER_VIEW));
} else {
return mInnerAdapter.onCreateViewHolder(parent, viewType - Integer.MAX_VALUE / 2);
}
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
int headerViewsCountCount = getHeaderViewsCount();
if (position >= headerViewsCountCount && position < headerViewsCountCount + mInnerAdapter.getItemCount()) {
mInnerAdapter.onBindViewHolder(holder, position - headerViewsCountCount);
} else {
ViewGroup.LayoutParams layoutParams = holder.itemView.getLayoutParams();
if(layoutParams instanceof StaggeredGridLayoutManager.LayoutParams) {
((StaggeredGridLayoutManager.LayoutParams) layoutParams).setFullSpan(true);
}
}
}
@Override
public int getItemCount() {
return getHeaderViewsCount() + getFooterViewsCount() + mInnerAdapter.getItemCount();
}
@Override
public int getItemViewType(int position) {
int innerCount = mInnerAdapter.getItemCount();
int headerViewsCountCount = getHeaderViewsCount();
if (position < headerViewsCountCount) {
return TYPE_HEADER_VIEW + position;
} else if (headerViewsCountCount <= position && position < headerViewsCountCount + innerCount) {
int innerItemViewType = mInnerAdapter.getItemViewType(position - headerViewsCountCount);
if(innerItemViewType >= Integer.MAX_VALUE / 2) {
throw new IllegalArgumentException("your adapter's return value of getViewTypeCount() must < Integer.MAX_VALUE / 2");
}
return innerItemViewType + Integer.MAX_VALUE / 2;
} else {
return TYPE_FOOTER_VIEW + position - headerViewsCountCount - innerCount;
}
}
public static class ViewHolder extends RecyclerView.ViewHolder {
public ViewHolder(View itemView) {
super(itemView);
}
}
}