package com.lean56.andplug.view.recycler; import android.content.Context; import android.content.res.TypedArray; import android.support.v4.widget.SwipeRefreshLayout; import android.support.v7.widget.RecyclerView; import android.util.AttributeSet; import android.view.LayoutInflater; import android.view.View; import android.view.ViewStub; import android.widget.FrameLayout; import com.github.ksoichiro.android.observablescrollview.ObservableRecyclerView; import com.github.ksoichiro.android.observablescrollview.ObservableScrollViewCallbacks; import com.lean56.andplug.R; /** * SuperRecyclerView * <p/> * ref. https://github.com/WuXiaolong/PullLoadMoreRecyclerView * ref. https://github.com/cymcsg/UltimateRecyclerView * * @author WuXiaolong * @author Charles */ public class SuperRecyclerView extends FrameLayout { // view protected SwipeRefreshLayout mPtrLayout; protected ObservableRecyclerView mRecycler; protected ViewStub mProgress; protected ViewStub mEmpty; protected View mProgressView; protected View mEmptyView; // attrs protected boolean mClipToPadding; protected int mPadding; protected int mPaddingTop; protected int mPaddingBottom; protected int mPaddingLeft; protected int mPaddingRight; protected int mScrollbarStyle; protected int mEmptyId; protected int mSuperRecyclerViewMainLayout; private int mProgressId; protected RecyclerView.OnScrollListener mInternalOnScrollListener; protected RecyclerView.OnScrollListener mExternalOnScrollListener; public SuperRecyclerView(Context context, AttributeSet attrs) { super(context, attrs); initAttrs(attrs); initViews(); } public SuperRecyclerView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); initAttrs(attrs); initViews(); } /** * init attrs * * @param attrs */ private void initAttrs(AttributeSet attrs) { TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.extendedrecyclerview); mSuperRecyclerViewMainLayout = a.getResourceId(R.styleable.extendedrecyclerview_mainLayoutId, R.layout.layout_progress_recyclerview); mClipToPadding = a.getBoolean(R.styleable.extendedrecyclerview_recyclerClipToPadding, false); mPadding = (int) a.getDimension(R.styleable.extendedrecyclerview_recyclerPadding, -1.0f); mPaddingTop = (int) a.getDimension(R.styleable.extendedrecyclerview_recyclerPaddingTop, 0.0f); mPaddingBottom = (int) a.getDimension(R.styleable.extendedrecyclerview_recyclerPaddingBottom, 0.0f); mPaddingLeft = (int) a.getDimension(R.styleable.extendedrecyclerview_recyclerPaddingLeft, 0.0f); mPaddingRight = (int) a.getDimension(R.styleable.extendedrecyclerview_recyclerPaddingRight, 0.0f); mScrollbarStyle = a.getInt(R.styleable.extendedrecyclerview_scrollbarStyle, -1); mEmptyId = a.getResourceId(R.styleable.extendedrecyclerview_layout_empty, 0); mProgressId = a.getResourceId(R.styleable.extendedrecyclerview_layout_progress, R.layout.layout_progress); a.recycle(); } /** * init views */ private void initViews() { if (isInEditMode()) { return; } View v = LayoutInflater.from(getContext()).inflate(mSuperRecyclerViewMainLayout, this); mPtrLayout = (SwipeRefreshLayout) v.findViewById(R.id.ptr_layout); mPtrLayout.setEnabled(false); mProgress = (ViewStub) v.findViewById(android.R.id.progress); mProgress.setLayoutResource(mProgressId); mProgressView = mProgress.inflate(); mEmpty = (ViewStub) v.findViewById(R.id.empty); mEmpty.setLayoutResource(mEmptyId); if (mEmptyId != 0) mEmptyView = mEmpty.inflate(); mEmpty.setVisibility(View.GONE); initRecyclerView(v); } /** * Implement this method to customize the AbsListView */ protected void initRecyclerView(View view) { View recyclerView = view.findViewById(android.R.id.list); if (recyclerView instanceof ObservableRecyclerView) mRecycler = (ObservableRecyclerView) recyclerView; else throw new IllegalArgumentException("SuperRecyclerView works with a RecyclerView!"); if (mRecycler != null) { mRecycler.setHasFixedSize(true); mRecycler.setClipToPadding(mClipToPadding); mInternalOnScrollListener = new RecyclerView.OnScrollListener() { @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) { super.onScrolled(recyclerView, dx, dy); if (mExternalOnScrollListener != null) mExternalOnScrollListener.onScrolled(recyclerView, dx, dy); } @Override public void onScrollStateChanged(RecyclerView recyclerView, int newState) { super.onScrollStateChanged(recyclerView, newState); if (mExternalOnScrollListener != null) mExternalOnScrollListener.onScrollStateChanged(recyclerView, newState); } }; mRecycler.addOnScrollListener(mInternalOnScrollListener); if (mPadding != -1.0f) { mRecycler.setPadding(mPadding, mPadding, mPadding, mPadding); } else { mRecycler.setPadding(mPaddingLeft, mPaddingTop, mPaddingRight, mPaddingBottom); } if (mScrollbarStyle != -1) { mRecycler.setScrollBarStyle(mScrollbarStyle); } } } /** * Set the layout manager to the recycler * * @param manager */ public void setLayoutManager(RecyclerView.LayoutManager manager) { mRecycler.setLayoutManager(manager); } /** * Set the adapter to the recycler * Automatically hide the progressbar * Set the refresh to false * If adapter is empty, then the emptyview is shown * * @param adapter */ public void setAdapter(RecyclerView.Adapter adapter) { mRecycler.setAdapter(adapter); mProgress.setVisibility(View.GONE); mRecycler.setVisibility(View.VISIBLE); mPtrLayout.setRefreshing(false); adapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() { @Override public void onItemRangeChanged(int positionStart, int itemCount) { super.onItemRangeChanged(positionStart, itemCount); update(); } @Override public void onItemRangeInserted(int positionStart, int itemCount) { super.onItemRangeInserted(positionStart, itemCount); update(); } @Override public void onItemRangeRemoved(int positionStart, int itemCount) { super.onItemRangeRemoved(positionStart, itemCount); update(); } @Override public void onItemRangeMoved(int fromPosition, int toPosition, int itemCount) { super.onItemRangeMoved(fromPosition, toPosition, itemCount); update(); } @Override public void onChanged() { super.onChanged(); update(); } private void update() { mProgress.setVisibility(View.GONE); mPtrLayout.setRefreshing(false); if (mRecycler.getAdapter().getItemCount() == 0 && mEmptyId != 0) { mEmpty.setVisibility(View.VISIBLE); } else if (mEmptyId != 0) { mEmpty.setVisibility(View.GONE); } } }); if ((adapter == null || adapter.getItemCount() == 0) && mEmptyId != 0) { mEmpty.setVisibility(View.VISIBLE); } else if (mEmptyId != 0) { mEmpty.setVisibility(View.GONE); } } /** * Set the empty adapter to the recycler * show the progressbar * hide recycler view ,empty view * adapter data should be empty * * @param adapter */ public void setProgressAdapter(RecyclerView.Adapter adapter) { mRecycler.setAdapter(adapter); mProgress.setVisibility(View.VISIBLE); mRecycler.setVisibility(View.GONE); mEmpty.setVisibility(View.GONE); mPtrLayout.setRefreshing(false); adapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() { @Override public void onItemRangeChanged(int positionStart, int itemCount) { super.onItemRangeChanged(positionStart, itemCount); update(); } @Override public void onItemRangeInserted(int positionStart, int itemCount) { super.onItemRangeInserted(positionStart, itemCount); update(); } @Override public void onItemRangeRemoved(int positionStart, int itemCount) { super.onItemRangeRemoved(positionStart, itemCount); update(); } @Override public void onItemRangeMoved(int fromPosition, int toPosition, int itemCount) { super.onItemRangeMoved(fromPosition, toPosition, itemCount); update(); } @Override public void onChanged() { super.onChanged(); update(); } private void update() { mProgress.setVisibility(View.GONE); mPtrLayout.setRefreshing(false); mRecycler.setVisibility(View.VISIBLE); if (mRecycler.getAdapter().getItemCount() == 0 && mEmptyId != 0) { mEmpty.setVisibility(View.VISIBLE); } else if (mEmptyId != 0) { mEmpty.setVisibility(View.GONE); } } }); } /** * Remove the adapter from the recycler */ public void clear() { mRecycler.setAdapter(null); } /** * Show the progressbar */ public void showProgress() { hideRecycler(); if (mEmptyId != 0) mEmpty.setVisibility(View.INVISIBLE); mProgress.setVisibility(View.VISIBLE); } /** * Hide the progressbar and show the recycler */ public void showRecycler() { hideProgress(); mRecycler.setVisibility(View.VISIBLE); } /** * Set the listener when refresh is triggered and enable the SwipeRefreshLayout * * @param listener */ public void setRefreshListener(SwipeRefreshLayout.OnRefreshListener listener) { mPtrLayout.setEnabled(true); mPtrLayout.setOnRefreshListener(listener); } /** * Set the colors for the SwipeRefreshLayout states * * @param colRes1 * @param colRes2 * @param colRes3 * @param colRes4 */ public void setRefreshingColorResources(int colRes1, int colRes2, int colRes3, int colRes4) { mPtrLayout.setColorSchemeResources(colRes1, colRes2, colRes3, colRes4); } /** * scrollToPosition of list * @param position */ public void scrollToPosition(int position) { mRecycler.getLayoutManager().scrollToPosition(position); } /** * Set the colors for the SwipeRefreshLayout states * * @param col1 * @param col2 * @param col3 * @param col4 */ public void setRefreshingColor(int col1, int col2, int col3, int col4) { mPtrLayout.setColorSchemeColors(col1, col2, col3, col4); } /** * Hide the progressbar */ public void hideProgress() { mProgress.setVisibility(View.GONE); } /** * Hide the recycler */ public void hideRecycler() { mRecycler.setVisibility(View.GONE); } /** * Set the scroll listener for the recycler * * @param listener */ public void setOnScrollListener(RecyclerView.OnScrollListener listener) { mExternalOnScrollListener = listener; } /** * Add the onItemTouchListener for the recycler * * @param listener */ public void addOnItemTouchListener(RecyclerView.OnItemTouchListener listener) { mRecycler.addOnItemTouchListener(listener); } /** * Remove the onItemTouchListener for the recycler * * @param listener */ public void removeOnItemTouchListener(RecyclerView.OnItemTouchListener listener) { mRecycler.removeOnItemTouchListener(listener); } /** * @return the recycler adapter */ public RecyclerView.Adapter getAdapter() { return mRecycler.getAdapter(); } public void setOnTouchListener(OnTouchListener listener) { mRecycler.setOnTouchListener(listener); } public void setItemAnimator(RecyclerView.ItemAnimator animator) { mRecycler.setItemAnimator(animator); } public void addItemDecoration(RecyclerView.ItemDecoration itemDecoration) { mRecycler.addItemDecoration(itemDecoration); } public void addItemDecoration(RecyclerView.ItemDecoration itemDecoration, int index) { mRecycler.addItemDecoration(itemDecoration, index); } public void removeItemDecoration(RecyclerView.ItemDecoration itemDecoration) { mRecycler.removeItemDecoration(itemDecoration); } /** * @return inflated progress view or null */ public View getProgressView() { return mProgressView; } /** * @return inflated empty view or null */ public View getEmptyView() { return mEmptyView; } public static enum LAYOUT_MANAGER_TYPE { LINEAR, GRID, STAGGERED_GRID } public void setScrollViewCallbacks(ObservableScrollViewCallbacks callbacks) { mRecycler.setScrollViewCallbacks(callbacks); } }