为RecyclerView添加头部和底部
第一步1
需要定义一个Adapter,继承自RecyclerView.Adapter
HeaderAndFooterWrapper<T> extends RecyclerView.Adapter<RecyclerView.ViewHolder>
第二步2
在Adapter的构造方法中传入一个Adapter对象用于添加除头部尾部以外的item,并生命所需要用的成员变量
private static final int BASE_ITEM_TYPE_HEADER = 10000;
private static final int BASE_ITEM_TYPE_FOOTER = 20000;
private SparseArrayCompat<View> mHeaderViews = new SparseArrayCompat<>();
private SparseArrayCompat<View> mFootViews = new SparseArrayCompat<>();
private RecyclerView.Adapter mInnerAdapter;
public HeaderAndFooterWrapper(RecyclerView.Adapter mInnerAdapter) {
this.mInnerAdapter = mInnerAdapter;
}
public boolean isHeaderViewPos(int position){
return position < getHeadersCount();
}
第三步3
需要有添加头部和尾部的方法,以及判断当前item是否是头部和尾部视图
public boolean isFooterViewPos(int position){
return position >= getHeadersCount() + getRealItemCount();
}
public void addHeaderView(View view){
mHeaderViews.put(mHeaderViews.size() + BASE_ITEM_TYPE_HEADER,view);
}
public void addFooterView(View view){
mFootViews.put(mFootViews.size() + BASE_ITEM_TYPE_FOOTER,view);
}
第四步4
添加获取每一种item数量的方法,比如header视图数量或者footer视图数量
private int getRealItemCount() {
return mInnerAdapter.getItemCount();
}
private int getHeadersCount() {
return mHeaderViews.size();
}
private int getFootersCount() {
return mFootViews.size();
}
@Override
public int getItemCount() {
return getHeadersCount() + getRealItemCount() + getFootersCount();
}
第五步5
复写getItemViewType方法,在该方法中判断如果是头部或者尾部视图就返回其在
private SparseArrayCompat mHeaderViews = new SparseArrayCompat<>();
private SparseArrayCompat mFootViews = new SparseArrayCompat<>();中的下标,以便获取
@Override
public int getItemViewType(int position) {
if(isHeaderViewPos(position)){
return mHeaderViews.keyAt(position);
}else if(isFooterViewPos(position)){
//如果当前是footerview 就计算出其在footerViews中的下标位置
return mFootViews.keyAt(position - getHeadersCount() - getRealItemCount());
}
return mInnerAdapter.getItemViewType(position - getHeadersCount());
}
第六步6
复写onCreateViewHolder方法,和onBindViewHolder方法
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if(mHeaderViews.get(viewType) != null){
ViewHolder vh = ViewHolder.crateViewHolder(parent.getContext(),
mHeaderViews.get(viewType));
return vh;
}else if(mFootViews.get(viewType) != null){
ViewHolder vh = ViewHolder.crateViewHolder(parent.getContext(),
mFootViews.get(viewType));
return vh;
}
return mInnerAdapter.onCreateViewHolder(parent,viewType);
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
if(isHeaderViewPos(position)){
return;
}else if(isFooterViewPos(position)){
return;
}
mInnerAdapter.onBindViewHolder(holder,position - getHeadersCount());
}
到此已经完成了添加头部的基本代码,但是如果需要在宫格布局下head依然占据一行的话需要添加一下代码
复写onAttachedToRecyclerView方法,在该方法中判断是否是GridLayoutManger,getSpanCount意思在构造GridLayoutManger的时候所传入的每行item数量,返回值的意思就是代表当前view所需要占据多少个item
@Override
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
mInnerAdapter.onAttachedToRecyclerView(recyclerView);
final RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();
if(layoutManager instanceof GridLayoutManager){
final GridLayoutManager gridLayoutManager = (GridLayoutManager) layoutManager;
gridLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
@Override
public int getSpanSize(int position) {
int viewType = getItemViewType(position);
if(mHeaderViews.get(viewType) != null){
return ((GridLayoutManager) layoutManager).getSpanCount();
}else if(mFootViews.get(viewType) != null){
return ((GridLayoutManager) layoutManager).getSpanCount();
}
return 1;
}
});
gridLayoutManager.setSpanCount(gridLayoutManager.getSpanCount());
}
}
本片文章参考自,仅仅用于个人学习笔记所用不喜勿喷
代码github地址