说明:
原文比较全的解析地址:RecyclerView添加Header的正确方式
这个是不带Header的简单RecyclerView用法:Android RecyclerView 使用方法
代码:
BaseRecyclerAdapter.java
/** * Created by qibin on 2015/11/5. */ public abstract class BaseRecyclerAdapter<T> extends RecyclerView.Adapter<RecyclerView.ViewHolder> { public static final int TYPE_HEADER = 0; public static final int TYPE_NORMAL = 1; private ArrayList<T> mDatas = new ArrayList<>(); private View mHeaderView; private OnItemClickListener mListener; public void setOnItemClickListener(OnItemClickListener li) { mListener = li; } public void setHeaderView(View headerView) { mHeaderView = headerView; notifyItemInserted(0); } public View getHeaderView() { return mHeaderView; } public void addDatas(ArrayList<T> datas) {//刷新数据 mDatas.addAll(datas); notifyDataSetChanged(); } @Override public int getItemViewType(int position) { if(mHeaderView == null) return TYPE_NORMAL; if(position == 0) return TYPE_HEADER; return TYPE_NORMAL; } @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, final int viewType) { if(mHeaderView != null && viewType == TYPE_HEADER) return new Holder(mHeaderView); return onCreate(parent, viewType); } @Override public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int position) { if(getItemViewType(position) == TYPE_HEADER) return; final int pos = getRealPosition(viewHolder); final T data = mDatas.get(pos); onBind(viewHolder, pos, data); if(mListener != null) { viewHolder.itemView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { mListener.onItemClick(pos, data); } }); } } @Override public void onAttachedToRecyclerView(RecyclerView recyclerView) { super.onAttachedToRecyclerView(recyclerView); RecyclerView.LayoutManager manager = recyclerView.getLayoutManager(); if(manager instanceof GridLayoutManager) { final GridLayoutManager gridManager = ((GridLayoutManager) manager); gridManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() { @Override public int getSpanSize(int position) { return getItemViewType(position) == TYPE_HEADER ? gridManager.getSpanCount() : 1; } }); } } @Override public void onViewAttachedToWindow(RecyclerView.ViewHolder holder) { super.onViewAttachedToWindow(holder); ViewGroup.LayoutParams lp = holder.itemView.getLayoutParams(); if(lp != null && lp instanceof StaggeredGridLayoutManager.LayoutParams && holder.getLayoutPosition() == 0) { StaggeredGridLayoutManager.LayoutParams p = (StaggeredGridLayoutManager.LayoutParams) lp; p.setFullSpan(true); } } public int getRealPosition(RecyclerView.ViewHolder holder) { int position = holder.getLayoutPosition(); return mHeaderView == null ? position : position - 1; } @Override public int getItemCount() { return mHeaderView == null ? mDatas.size() : mDatas.size() + 1; } public abstract RecyclerView.ViewHolder onCreate(ViewGroup parent, final int viewType); public abstract void onBind(RecyclerView.ViewHolder viewHolder, int RealPosition, T data); public class Holder extends RecyclerView.ViewHolder { public Holder(View itemView) { super(itemView); } } public interface OnItemClickListener<T> { void onItemClick(int position, T data); } }
我们将BaseRecyclerAdapter抽象起来,并且提供两个抽象方法onCreate和onBind用来创建holder和绑定数据,而对于header做的一系列工作,我们都放到了BaseRecyclerAdapter中,而继承BaseRecyclerAdapter后,我们仅仅关心我们的holder怎么创建和数据怎么绑定就ok。例如下面代码:
MyAdapter.java
/** * Created by qibin on 2015/11/7. */ public class MyAdapter extends BaseRecyclerAdapter<String> { @Override public RecyclerView.ViewHolder onCreate(ViewGroup parent, int viewType) { View layout = LayoutInflater.from(parent.getContext()).inflate(R.layout.item, parent, false); return new MyHolder(layout); } @Override public void onBind(RecyclerView.ViewHolder viewHolder, int RealPosition, String data) { if(viewHolder instanceof MyHolder) { ((MyHolder) viewHolder).text.setText(data); } } class MyHolder extends BaseRecyclerAdapter.Holder { TextView text; public MyHolder(View itemView) { super(itemView); text = (TextView) itemView.findViewById(R.id.text); } } }