通过重写OnScrollListener来监听RecyclerView是否滑动到底部
为了增加复用性和灵活性,我们还是定义一个接口来做监听滚动到底部的回调,这样你就可以把它用在listview,scrollView中去。
OnBottomListener
package kale.com.waterfall; /** * @author Jack Tony * @brief * @date 2015/4/6 */ public interface OnBottomListener { public void onBottom(); }
接着,我们来重写RecyclerView.OnScrollListener
package kale.com.waterfall.extra.RecyclerView; import android.support.v7.widget.GridLayoutManager; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.StaggeredGridLayoutManager; import kale.com.waterfall.OnBottomListener; /** * @author Jack Tony * @brief recyle view 滚动监听器 * @date 2015/4/6 */ public class OnRcvScrollListener extends RecyclerView.OnScrollListener implements OnBottomListener { private String TAG = getClass().getSimpleName(); public static enum LAYOUT_MANAGER_TYPE { LINEAR, GRID, STAGGERED_GRID } /** * layoutManager的类型(枚举) */ protected LAYOUT_MANAGER_TYPE layoutManagerType; /** * 最后一个的位置 */ private int[] lastPositions; /** * 最后一个可见的item的位置 */ private int lastVisibleItemPosition; /* *//** * 是否正在加载 *//* private boolean isLoadingMore = false;*/ /** * 当前滑动的状态 */ private int currentScrollState = 0; @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) { super.onScrolled(recyclerView, dx, dy); RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager(); // int lastVisibleItemPosition = -1; if (layoutManagerType == null) { if (layoutManager instanceof LinearLayoutManager) { layoutManagerType = LAYOUT_MANAGER_TYPE.LINEAR; } else if (layoutManager instanceof GridLayoutManager) { layoutManagerType = LAYOUT_MANAGER_TYPE.GRID; } else if (layoutManager instanceof StaggeredGridLayoutManager) { layoutManagerType = LAYOUT_MANAGER_TYPE.STAGGERED_GRID; } else { throw new RuntimeException( "Unsupported LayoutManager used. Valid ones are LinearLayoutManager, GridLayoutManager and StaggeredGridLayoutManager"); } } switch (layoutManagerType) { case LINEAR: lastVisibleItemPosition = ((LinearLayoutManager) layoutManager) .findLastVisibleItemPosition(); break; case GRID: lastVisibleItemPosition = ((GridLayoutManager) layoutManager) .findLastVisibleItemPosition(); break; case STAGGERED_GRID: StaggeredGridLayoutManager staggeredGridLayoutManager = (StaggeredGridLayoutManager) layoutManager; if (lastPositions == null) { lastPositions = new int[staggeredGridLayoutManager.getSpanCount()]; } staggeredGridLayoutManager.findLastVisibleItemPositions(lastPositions); lastVisibleItemPosition = findMax(lastPositions); break; } } @Override public void onScrollStateChanged(RecyclerView recyclerView, int newState) { super.onScrollStateChanged(recyclerView, newState); currentScrollState = newState; RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager(); int visibleItemCount = layoutManager.getChildCount(); int totalItemCount = layoutManager.getItemCount(); if ((visibleItemCount > 0 && currentScrollState == RecyclerView.SCROLL_STATE_IDLE && (lastVisibleItemPosition) >= totalItemCount - 1)) { //Log.d(TAG, "is loading more"); onBottom(); } } @Override public void onBottom() { //Log.d(TAG, "is onBottom"); } private int findMax(int[] lastPositions) { int max = lastPositions[0]; for (int value : lastPositions) { if (value > max) { max = value; } } return max; } }
在之后的使用中,我们就可以像下方这样监听回调方法了:
waterFallRcv.setOnScrollListener(new OnRcvScrollListener(){ @Override public void onBottom() { super.onBottom(); // 到底部自动加载 if (!isLoadingData){ Log.d(TAG, "loading old data"); adapter.loadOldData(); isLoadingData = true; } } });