添加header的思路就是通过adapter的itemType来加载不同的布局。
又根据LayoutManager有不同的处理方式。
1、线性布局LinearLayoutManager
简单,只需要根据不同的itemType处理不同的ViewHolder就能实现。
设置布局管理器:
RecyclerView.LayoutManager manager = new LinearLayoutManager(this,LinearLayoutManager.VERTICAL,false);
rv.setLayoutManager(manager);
rv.setAdapter(new MyAdapter(arrays));
不同的viewHolder:
static class MyHolder extends RecyclerView.ViewHolder{
public TextView tv;
public MyHolder(View itemView) {
super(itemView);
tv = (TextView) itemView.findViewById(R.id.tv_rv_header_item);
}
}
static class MyHeaderHolder extends RecyclerView.ViewHolder{
public ImageView iv;
public MyHeaderHolder(View itemView) {
super(itemView);
iv = (ImageView) itemView.findViewById(R.id.iv_rv_header_header);
}
}
复写adapter的getItemViewType方法:
@Override
public int getItemViewType(int position) {
return position == 0 ? ITEM_TYPE.HEADER.ordinal():ITEM_TYPE.NORMAL.ordinal();
}
在adapter的onCreateViewHolder中根据itemType生成不同的holder:
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
RecyclerView.ViewHolder holder;
if(viewType == ITEM_TYPE.HEADER.ordinal()){
holder = new MyHeaderHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.rv_header_header,parent,false));
}else{
holder = new MyHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.rv_header_item, parent, false));
}
return holder;
}
这样默认第0行就是headerView了。
2、表格布局GridLayoutManager的情况。
需要用到GridLayoutManager的setSpanSizeLookup这个方法,这个方法需要传入一个抽象类
SpanSizeLookup,在这个类中实现
getSpanSize方法。这个方法的返回值决定了我们每个position上的item占据的单元格个数,比如设置了manager是2列数据,那么header所在的item就需要占据两个单元格:
GridLayoutManager manager = new GridLayoutManager(this,2);
rv.setLayoutManager(manager);
复写adapter的onAttachToRecyclerView,这个方法是adapter设置给了recyclerView时回调的,在该方法里面可以得到具体的manager,通过这个manager来处理item的占据单元格的问题:
@Override
public void onAttachedToRecyclerView(final RecyclerView recyclerView) {
super.onAttachedToRecyclerView(recyclerView);
RecyclerView.LayoutManager manager = recyclerView.getLayoutManager();
if(manager instanceof GridLayoutManager){
final GridLayoutManager gridLayoutManager = (GridLayoutManager) manager;
gridLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
@Override
public int getSpanSize(int position) {
return getItemViewType(position)==ITEM_TYPE.HEADER.ordinal()? gridLayoutManager.getSpanCount():1;
}
});
}
}
先判断是否是表格布局,是的话就根据itemType返回item所占的单元格。
3、瀑布流布局StaggeredGridLayoutManager的情况
又需要重写adapter的另外一个方法onViewAttachToWindow。这里的处理方式是用通过
LayoutParams
,而且这里更简单,
StaggeredGridLayoutManager.LayoutParams
为我们提供了一个
setFullSpan
方法来设置占领全部空间。
@Override
public void onViewAttachedToWindow(RecyclerView.ViewHolder holder) {
super.onViewAttachedToWindow(holder);
ViewGroup.LayoutParams lp = holder.itemView.getLayoutParams();
if(lp != null && lp instanceof StaggeredGridLayoutManager.LayoutParams){
StaggeredGridLayoutManager.LayoutParams layoutParams = (StaggeredGridLayoutManager.LayoutParams) lp;
layoutParams.setFullSpan(holder.getLayoutPosition()==0);
}
}