现在项目里将Listview都替换成了用Recyclerview来实现,所以很多地方都需要监听Recyclerview是否滑动到底部然后触发某些操作。
通过添加Recyclerview的OnScrollListener来判断Recyclerview是否滑动到底部。具体代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { @Override public void onScrollStateChanged(RecyclerView recyclerView, int newState) { int lastPosition = -1;
if(newState == RecyclerView.SCROLL_STATE_IDLE){ RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager(); if(layoutManager instanceof GridLayoutManager){ lastPosition = ((GridLayoutManager) layoutManager).findLastVisibleItemPosition(); }else if(layoutManager instanceof LinearLayoutManager){ lastPosition = ((LinearLayoutManager) layoutManager).findLastVisibleItemPosition(); }else if(layoutManager instanceof StaggeredGridLayoutManager){ int[] lastPositions = new int[((StaggeredGridLayoutManager) layoutManager).getSpanCount()]; ((StaggeredGridLayoutManager) layoutManager).findLastVisibleItemPositions(lastPositions); lastPosition = findMax(lastPositions); }
if(lastPosition == recyclerView.getLayoutManager().getItemCount()-1){ Toast.makeText(RecyclerActivity.this, "滑动到底了", Toast.LENGTH_SHORT).show(); }
} }
@Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
}
});
|
findMax方法:
1 2 3 4 5 6 7 8 9 10
| private int findMax(int[] lastPositions) { int max = lastPositions[0]; for (int value : lastPositions) { if (value > max) { max = value; } } return max; }
|
通过添加对RecyclerView的滑动事件,在滑动状态改变的回调里当滑动停止的时候通过layout找到当前RecyclerView显示的最后一个item的position,然后判断这个position是否为Recyclerview的最后一个item的position值,如果是的话则表示已经滑动到最底部了。
上面的代码基本上已经实现了对滑动到底部的监听,只需要将上面的Toast弹出提示的代码替换成我们自己的处理就可以了。但是上面的代码也有一个bug,当最后一个item刚显示出来的时候停止滑动这个时候也会触发滑动到底部的操作,有时候我们可能并不希望这,希望当Recyclerview确实是滑动到底部滑动不了的时候才触发。
修改上面的代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { @Override public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
}
@Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
View lastChildView = recyclerView.getLayoutManager().getChildAt(recyclerView.getLayoutManager().getChildCount()-1); int lastChildBottom = lastChildView.getBottom(); int recyclerBottom = recyclerView.getBottom()-recyclerView.getPaddingBottom(); int lastPosition = recyclerView.getLayoutManager().getPosition(lastChildView);
if(lastChildBottom == recyclerBottom && lastPosition == recyclerView.getLayoutManager().getItemCount()-1 ){ Toast.makeText(RecyclerActivity.this, "滑动到底了", Toast.LENGTH_SHORT).show(); } }
});
|
上面的代码是在onScrolled的回调中获取layoutManager最后一个childView,获得childView的底部坐标和当前childView的position值,判断childView的底部坐标是否跟Recyclerview的底部坐标相等以及当前position是否是最后一个position值,如果都满足的话说明是真正的滑动到底部了。
注意:上面的判断是在onScrolled中书写的,每滑动一下都会去判断一次,也可以将这段代码放到onScrollStateChanged回调中当停止滑动的时候再去判断,类似于第一种方法那样。可以根据具体的业务需求进行修改