recyclerView通用适配器,支持添加多个header和footer

来源:互联网 发布:淘宝网真皮包包 编辑:程序博客网 时间:2024/06/04 18:48

recyclerView通用适配器,支持添加多个header和footer

每个RecyclerView都要写一个适配器很浪费时间。

  1. 设置header和footer就是RecyclerView设置不同type的Item。
  2. onCreatedViewHolder()绑定不同布局(item),抽象出一个方法getItemLayoutId()。
  3. 绑定数据onBindViewHolder中设置了一个onBind()方法。
  4. 给item设置点击事件,已经把header和footer的item的点击事件屏蔽了

以下是全部代码:

package com.lanjiejie.adapter;import android.content.Context;import android.support.v7.widget.GridLayoutManager;import android.support.v7.widget.RecyclerView;import android.support.v7.widget.StaggeredGridLayoutManager;import android.util.Log;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import java.util.ArrayList;import java.util.List;/** * recyclerView 适配器 */public abstract class BaseRecycleViewAdapter<T> extends RecyclerView.Adapter<BaseRecyclerViewHolder> {    public static final int TYPE_NORMAL = 1;    private static final int TYPE_FLAG = 100000;    private Context mContext;    private List<T> mDataList;    private LayoutInflater mLayoutInflater;    private List<View> mHeaderViews = new ArrayList<>();    private List<View> mFooterViews = new ArrayList<>();    private List<Integer> mHeaderViewTypes = new ArrayList<>();    private List<Integer> mFooterViewTypes = new ArrayList<>();    private OnItemClickListener mClickListener;    public BaseRecycleViewAdapter(Context context, List<T> dataList) {        this.mContext = context;        this.mDataList = dataList;        mLayoutInflater = LayoutInflater.from(mContext);    }    @Override    public BaseRecyclerViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {        if (mHeaderViewTypes.contains(viewType)) {            return new BaseRecyclerViewHolder(mContext, mHeaderViews.get(viewType / TYPE_FLAG));        }        if (mFooterViewTypes.contains(viewType)) {            int index = viewType / TYPE_FLAG - mDataList.size() - mHeaderViews.size();            return new BaseRecyclerViewHolder(mContext, mFooterViews.get(index));        }        return new BaseRecyclerViewHolder(mContext, mLayoutInflater.inflate(getItemLayoutId(viewType), parent, false));    }    @Override    public void onBindViewHolder(final BaseRecyclerViewHolder holder, final int position) {        if (isFooter(position) || isHeader(position))            return;        final int realPos = getRealPosition(position);        if (realPos < mDataList.size()) {            final T data = mDataList.get(realPos);            onBind(holder, realPos, data);        }        if (mClickListener != null) {            holder.itemView.setOnClickListener(new View.OnClickListener() {                @Override                public void onClick(View v) {                    mClickListener.onItemClick(holder.itemView, realPos);                }            });        }    }    @Override    public int getItemCount() {        return mDataList.size() + mHeaderViews.size() + mFooterViews.size();    }    @Override    public int getItemViewType(int position) {        if (mHeaderViews.size() > 0 && position < mHeaderViews.size()) {            //用position作为HeaderView 的   ViewType标记            //记录每个ViewType标记            mHeaderViewTypes.add(position * TYPE_FLAG);            return position * TYPE_FLAG;        }        if (mFooterViews.size() > 0 && mFooterViews.size() > 0 && position >= getItemCount() - mFooterViews.size()) {            //用position作为FooterView 的   ViewType标记            //记录每个ViewType标记            mFooterViewTypes.add(position * TYPE_FLAG);            return position * TYPE_FLAG;        }        return TYPE_NORMAL;    }    public int getRealPosition(int position) {        return position - mHeaderViews.size();    }    /**     * 必须在setAdapter之前添加     *     * @param view header     */    public void addHeaderView(View view) {        mHeaderViews.add(view);    }    /**     * 必须在setAdapter之前添加     *     * @param view footer     */    public void addFooterView(View view) {        mFooterViews.add(view);    }    private boolean isHeader(int position) {        return mHeaderViews.size() > 0 && position < mHeaderViews.size();    }    private boolean isFooter(int position) {        return mFooterViews.size() > 0 && position >= getItemCount() - mFooterViews.size();    }    /**     * 当LayoutManager是GridLayoutManager时,设置header和footer占据的列数     * @param recyclerView recyclerView     */    @Override    public void onAttachedToRecyclerView(RecyclerView recyclerView) {        super.onAttachedToRecyclerView(recyclerView);        final RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();        if (layoutManager instanceof GridLayoutManager) {            final GridLayoutManager gridManager = ((GridLayoutManager) layoutManager);            gridManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {                @Override                public int getSpanSize(int position) {                    return (isFooter(position) || isHeader(position))                            ? gridManager.getSpanCount() : 1;                }            });        }    }    /**     * 当LayoutManager是StaggeredGridLayoutManager时,设置header和footer占据的列数     * @param holder holder     */    @Override    public void onViewAttachedToWindow(BaseRecyclerViewHolder holder) {        super.onViewAttachedToWindow(holder);        final ViewGroup.LayoutParams layoutParams = holder.itemView.getLayoutParams();        if (layoutParams != null && layoutParams instanceof StaggeredGridLayoutManager.LayoutParams) {            StaggeredGridLayoutManager.LayoutParams params = (StaggeredGridLayoutManager.LayoutParams) layoutParams;            params.setFullSpan(isHeader(holder.getLayoutPosition())                    || isFooter(holder.getLayoutPosition()));        }    }    /**     * 绑定数据     * @param viewHolder holder     * @param position pos     * @param data 数据源     */    public abstract void onBind(BaseRecyclerViewHolder viewHolder, int position, T data);    /**     * item 布局id     *     * @param viewType item type     * @return item 布局id     */    abstract public int getItemLayoutId(int viewType);    public interface OnItemClickListener {        void onItemClick(View itemView, int pos);        void onItemLongClick(View itemView, int pos);    }    public void setOnItemClickListener(OnItemClickListener listener) {        mClickListener = listener;    }}

ViewHolder仿照鸿洋大神的listView的holder

public class BaseRecyclerViewHolder extends RecyclerView.ViewHolder {    private SparseArray<View> mViews;    private Context mContext;    public BaseRecyclerViewHolder(Context context, View itemView) {        super(itemView);        this.mContext = context;        mViews = new SparseArray<>();    }    private <T extends View> T findViewById(int viewId) {        View view = mViews.get(viewId);        if (view == null) {            view = itemView.findViewById(viewId);            mViews.put(viewId, view);        }        return (T) view;    }    public View getView(int viewId) {        return findViewById(viewId);    }}

需要注意:

  1. 绑定数据源时的position,记得有几个header就减去几。参见:方法getRealPosition()
0 0