加载更多的RecyclerView的Adapter - LoadMoreAdapter

public abstract class LoadMoreAdapter<B> extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
    protected List<B> datas;
    private int page = 1;
    //标记底部显示状态
    protected int                   hasMore;
    protected   LoadMoreListener      loadMoreListener = null;
    protected   IdLoadMoreListener<B> idLoadMoreListener = null;
    protected OnRecyclerViewItemClickListener<B> mOnItemClickListener = null;
    protected Context               context;
    //记录尾部的当前位置,防止onBindViewHolder()多次调用里面的操作
    private int pos = -1;

    public LoadMoreAdapter(Context context) {
        this.context = context;
    }
    enum ViewType {
        CONTENT, LOADMORE,
    }

    enum Load {
        EMPTY, ERROR, LOADING
    }

    /**
     * @return  请求的数据数
     */
    public abstract int getPageSize();

    /**
     * 设置是否可加载更多
     */
    protected abstract boolean getHasLoadMore();
    /**
     * 设置更多数据item变成加载出错
     */
    public void setErrorLoad() {
        pos = -1;
        hasMore = Load.ERROR.ordinal();
        notifyItemChanged(getItemCount() - 1);
    }
    public void setLoadMoreListener(LoadMoreListener loadMoreListener) {
        this.loadMoreListener = loadMoreListener;
    }
    public void setIdLoadMoreListener(IdLoadMoreListener<B> idLoadMoreListener) {
        this.idLoadMoreListener = idLoadMoreListener;
    }


    /**
     * 设置RecyclerView
     * @param rv
     * @param spanSize  1行有几个item
     */
    public void bindRecyclerView(RecyclerView rv, final int spanSize){
        GridLayoutManager gridLayoutManager = new GridLayoutManager(context,spanSize);
        gridLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
            @Override
            public int getSpanSize(int position) {
                if (getHasLoadMore()) {
                    return datas == null ? 0 : getItemCount() - 1 == position ? spanSize : 1;
                } else {
                    return datas == null ? 0 : 1;
                }
            }
        });
        rv.setLayoutManager(gridLayoutManager);
        rv.setHasFixedSize(true);
        rv.setAdapter(this);
    }
    /**
     * @param data null-->加载更多数据时,没有数据就传null,加载更多item就变成没有更多数据
     */
    public void addData(List<B> data) {
        if (data != null && data.size() >= getPageSize()) {
            hasMore = Load.LOADING.ordinal();
        } else {
            hasMore = Load.EMPTY.ordinal();
            if (data == null||data.size()==0) {
                pos = -1;//不然刷新后,加载更多item没改变
                notifyItemChanged(getItemCount() - 1);
                return;
            }
        }
        if (datas == null) {
            datas = new ArrayList<>();
        }
        datas.addAll(data);
        notifyDataSetChanged();
    }
    public List<B> getDatas() {
        return datas;
    }
    public void setData(List<B> data) {
        pos = -1;//不然刷新后,加载更多item没改变
        if (data != null && data.size() >= getPageSize()) {
            hasMore = Load.LOADING.ordinal();
        } else {
            hasMore = Load.EMPTY.ordinal();
        }
        if (datas != null)
            datas.clear();
        datas = data;
        page = 1;
        notifyDataSetChanged();
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        if (viewType == ViewType.LOADMORE.ordinal()) {
            return new LoadMoreViewHolder(LayoutInflater.from(context).inflate(R.layout.loadmore_item, parent, false));
        } else {
            RecyclerView.ViewHolder holder = new ViewHolder(LayoutInflater.from(context).inflate(resId(), parent, false));
            holder.itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (mOnItemClickListener != null && getItemCount()>0) {
                        mOnItemClickListener.onItemClick(v, viewType, datas.get(holder.getAdapterPosition()), holder.getAdapterPosition());
                    }
                }
            });
            return holder;
        }
    }

    public abstract int resId();

    public abstract void bindViewHolder(ViewHolder holder, B data, int position);

    @Override
    public void onBindViewHolder(final RecyclerView.ViewHolder holder, int position) {
        if (holder instanceof LoadMoreViewHolder) {
            if (pos == position) {//防止listener多次回调
                return;
            } else {
                pos = position;
            }
            final View loading = ((LoadMoreViewHolder) holder).loading;
            View empty = ((LoadMoreViewHolder) holder).empty;
            final View error = ((LoadMoreViewHolder) holder).error;
            loading.setVisibility(View.GONE);
            empty.setVisibility(View.GONE);
            error.setVisibility(View.GONE);
            if (hasMore == Load.LOADING.ordinal()) {
                loading.setVisibility(View.VISIBLE);
                if (loadMoreListener!=null) {
                    loadMoreListener.onLoadMore(++page);
                }
                if (idLoadMoreListener!=null&&datas!=null) {
                    idLoadMoreListener.onLoadMore(datas.get(position - 1));
                }
            } else if (hasMore == Load.EMPTY.ordinal()) {
                empty.setVisibility(View.VISIBLE);
            } else if (hasMore == Load.ERROR.ordinal()){
                error.setVisibility(View.VISIBLE);
                error.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        error.setVisibility(View.GONE);
                        loading.setVisibility(View.VISIBLE);
                        if (loadMoreListener!=null)
                            loadMoreListener.onLoadMore(page);
                        if (idLoadMoreListener!=null&&datas!=null)
                            idLoadMoreListener.onLoadMore(datas.get(holder.getAdapterPosition()-1));
                    }
                });
            }
        }
        if (holder instanceof ViewHolder) {
            bindViewHolder((ViewHolder) holder, datas.get(position), position);
        }
    }

    @Override
    public int getItemViewType(int position) {
        if (getHasLoadMore()) {
            if (position == getItemCount() - 1) {
                return ViewType.LOADMORE.ordinal();
            }
            return ViewType.CONTENT.ordinal();
        } else {
            return ViewType.CONTENT.ordinal();
        }
    }

    @Override
    public int getItemCount() {
        if (getHasLoadMore()) {
            return datas == null ? 0 : datas.size() + 1;//+1 加载更多item
        } else {
            return datas == null ? 0 : datas.size();
        }
    }

    public static class ViewHolder extends RecyclerView.ViewHolder {
        private SparseArray<View> mViews;

        public ViewHolder(View itemView) {
            super(itemView);
            mViews = new SparseArray<>();
        }

        /**
         * 用于查找 View
         */
        public <V extends View> V getView(int id) {
            View view = mViews.get(id);
            if (view == null) {
                view = itemView.findViewById(id);
                mViews.append(id, view);
            }
            return (V) view;
        }
    }

    public interface LoadMoreListener {
        public void onLoadMore(int page);
    }

    public interface IdLoadMoreListener<B> {
        public void onLoadMore(B data);
    }
    public interface OnRecyclerViewItemClickListener<B> {
        void onItemClick(View view, int viewType, B data, int position);
    }

    public void setOnItemClickListener(OnRecyclerViewItemClickListener<B> listener) {
        this.mOnItemClickListener = listener;
    }
    public static class LoadMoreViewHolder extends RecyclerView.ViewHolder{
        public View loading;
        public View error;
        public View empty;
        public LoadMoreViewHolder(View itemView) {
            super(itemView);
            loading = itemView.findViewById(R.id.view_loading);
            error = itemView.findViewById(R.id.view_error);
            empty = itemView.findViewById(R.id.view_empty);
        }
    }
}

猜你喜欢

转载自blog.csdn.net/u010505059/article/details/81483820
今日推荐