package ren.solid.library.widget.loadmore; import android.content.Context; import android.support.v7.widget.GridLayoutManager; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.StaggeredGridLayoutManager; import android.view.Gravity; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; import static android.view.ViewGroup.LayoutParams.MATCH_PARENT; import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT; /** * Created by _SOLID * Date:2016/9/29 * Time:9:30 * Desc:load more wrap adapter for recyclerview */ public class LoadMoreWrapper extends RecyclerView.Adapter<RecyclerView.ViewHolder> { public static final int ITEM_TYPE_LOAD_FAILED_VIEW = Integer.MAX_VALUE - 1; public static final int ITEM_TYPE_NO_MORE_VIEW = Integer.MAX_VALUE - 2; public static final int ITEM_TYPE_LOAD_MORE_VIEW = Integer.MAX_VALUE - 3; public static final int ITEM_TYPE_NO_VIEW = Integer.MAX_VALUE - 4;//不展示footer view private Context mContext; private RecyclerView.Adapter mInnerAdapter; private View mLoadMoreView; private View mLoadMoreFailedView; private View mNoMoreView; private int mCurrentItemType = ITEM_TYPE_LOAD_MORE_VIEW; private LoadMoreScrollListener mLoadMoreScrollListener; private boolean isLoadError = false;//标记是否加载出错 private boolean isHaveStatesView = true; public LoadMoreWrapper(Context context, RecyclerView.Adapter adapter) { this.mContext = context; this.mInnerAdapter = adapter; mLoadMoreScrollListener = new LoadMoreScrollListener() { @Override public void loadMore() { if (mOnLoadListener != null && isHaveStatesView) { if (!isLoadError) { showLoadMore(); mOnLoadListener.onLoadMore(); } } } }; } public void showLoadMore() { mCurrentItemType = ITEM_TYPE_LOAD_MORE_VIEW; isLoadError = false; isHaveStatesView = true; notifyItemChanged(getItemCount()); } public void showLoadError() { mCurrentItemType = ITEM_TYPE_LOAD_FAILED_VIEW; isLoadError = true; isHaveStatesView = true; notifyItemChanged(getItemCount()); } public void showLoadComplete() { mCurrentItemType = ITEM_TYPE_NO_MORE_VIEW; isLoadError = false; isHaveStatesView = true; notifyItemChanged(getItemCount()); } public void disableLoadMore() { mCurrentItemType = ITEM_TYPE_NO_VIEW; isHaveStatesView = false; notifyDataSetChanged(); } //region Get ViewHolder private ViewHolder getLoadMoreViewHolder() { if (mLoadMoreView == null) { mLoadMoreView = new TextView(mContext); mLoadMoreView.setLayoutParams(new ViewGroup.LayoutParams(MATCH_PARENT, WRAP_CONTENT)); mLoadMoreView.setPadding(20, 20, 20, 20); ((TextView) mLoadMoreView).setText("正在努力加载中..."); ((TextView) mLoadMoreView).setGravity(Gravity.CENTER); } return new ViewHolder(mLoadMoreView); } private ViewHolder getLoadFailedViewHolder() { if (mLoadMoreFailedView == null) { mLoadMoreFailedView = new TextView(mContext); mLoadMoreFailedView.setPadding(20, 20, 20, 20); mLoadMoreFailedView.setLayoutParams(new ViewGroup.LayoutParams(MATCH_PARENT, WRAP_CONTENT)); ((TextView) mLoadMoreFailedView).setText("加载失败,请点我重试"); ((TextView) mLoadMoreFailedView).setGravity(Gravity.CENTER); } return new ViewHolder(mLoadMoreFailedView); } private ViewHolder getNoMoreViewHolder() { if (mNoMoreView == null) { mNoMoreView = new TextView(mContext); mNoMoreView.setPadding(20, 20, 20, 20); mNoMoreView.setLayoutParams(new ViewGroup.LayoutParams(MATCH_PARENT, WRAP_CONTENT)); ((TextView) mNoMoreView).setText("-- end --"); ((TextView) mNoMoreView).setGravity(Gravity.CENTER); } return new ViewHolder(mNoMoreView); } //endregion @Override public int getItemViewType(int position) { if (position == getItemCount() - 1 && isHaveStatesView) { return mCurrentItemType; } return mInnerAdapter.getItemViewType(position); } @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { if (viewType == ITEM_TYPE_NO_MORE_VIEW) { return getNoMoreViewHolder(); } else if (viewType == ITEM_TYPE_LOAD_MORE_VIEW) { return getLoadMoreViewHolder(); } else if (viewType == ITEM_TYPE_LOAD_FAILED_VIEW) { return getLoadFailedViewHolder(); } return mInnerAdapter.onCreateViewHolder(parent, viewType); } @Override public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { if (holder.getItemViewType() == ITEM_TYPE_LOAD_FAILED_VIEW) { mLoadMoreFailedView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (mOnLoadListener != null) { mOnLoadListener.onRetry(); showLoadMore(); } } }); return; } if (!isFooterType(holder.getItemViewType())) mInnerAdapter.onBindViewHolder(holder, position); } @Override public void onAttachedToRecyclerView(RecyclerView recyclerView) { WrapperUtils.onAttachedToRecyclerView(mInnerAdapter, recyclerView, new WrapperUtils.SpanSizeCallback() { @Override public int getSpanSize(GridLayoutManager layoutManager, GridLayoutManager.SpanSizeLookup oldLookup, int position) { if (position == getItemCount() - 1 && isHaveStatesView) { return layoutManager.getSpanCount(); } if (oldLookup != null && isHaveStatesView) { return oldLookup.getSpanSize(position); } return 1; } }); recyclerView.addOnScrollListener(mLoadMoreScrollListener); } @Override public void onViewAttachedToWindow(RecyclerView.ViewHolder holder) { mInnerAdapter.onViewAttachedToWindow(holder); if (holder.getLayoutPosition() == getItemCount() - 1 && isHaveStatesView) { ViewGroup.LayoutParams lp = holder.itemView.getLayoutParams(); if (lp != null && lp instanceof StaggeredGridLayoutManager.LayoutParams) { StaggeredGridLayoutManager.LayoutParams p = (StaggeredGridLayoutManager.LayoutParams) lp; p.setFullSpan(true); } } } @Override public int getItemCount() { return mInnerAdapter.getItemCount() + (isHaveStatesView ? 1 : 0); } public boolean isFooterType(int type) { return type == ITEM_TYPE_NO_VIEW || type == ITEM_TYPE_LOAD_FAILED_VIEW || type == ITEM_TYPE_NO_MORE_VIEW || type == ITEM_TYPE_LOAD_MORE_VIEW; } public class ViewHolder extends RecyclerView.ViewHolder { public ViewHolder(View itemView) { super(itemView); } } //region 加载监听 public interface OnLoadListener { void onRetry(); void onLoadMore(); } private OnLoadListener mOnLoadListener; public LoadMoreWrapper setOnLoadListener(OnLoadListener onLoadListener) { mOnLoadListener = onLoadListener; return this; } //endregion }