上拉加载更多数据通过监听RecyclerView的滚动事件RecyclerView.OnScrollListener()实现的,它提供了两个方法:
/**
* 当RecyclerView的滑动状态改变时触发
*/
public void onScrollStateChanged(RecyclerView recyclerView, int newState){}
/**
* 当RecyclerView滑动时触发
* 类似点击事件的MotionEvent.ACTION_MOVE
*/
public void onScrolled(RecyclerView recyclerView, int dx, int dy){}
RecyclerView的滑动状态有如下三种:
/**
* The RecyclerView is not currently scrolling.
* 手指离开屏幕
*/
public static final int SCROLL_STATE_IDLE = 0;
/**
* The RecyclerView is currently being dragged by outside input such as user touch input.
* 手指触摸屏幕
*/
public static final int SCROLL_STATE_DRAGGING = 1;
/**
* The RecyclerView is currently animating to a final position while not under
* outside control.
* 手指加速滑动并放开,此时滑动状态伴随SCROLL_STATE_IDLE
*/
public static final int SCROLL_STATE_SETTLING = 2;
第一种实现:滑动到最后一个item时自动触发的
与手指是否在屏幕上无关,即与滑动状态无关。因此,实现这种效果只需要在public void onScrolled(RecyclerView recyclerView, int dx, int dy) 方法中操作,无需关注当时的滑动状态:
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
Log.d("test", "onScrolled");
int lastVisibleItemPosition = layoutManager.findLastVisibleItemPosition();
if (lastVisibleItemPosition + 1 == adapter.getItemCount()) {
Log.d("test", "loading executed");
boolean isRefreshing = swipeRefreshLayout.isRefreshing();
if (isRefreshing) {
adapter.notifyItemRemoved(adapter.getItemCount());
return;
}
if (!isLoading) {
isLoading = true;
handler.postDelayed(new Runnable() {
@Override
public void run() {
getData();
Log.d("test", "load more completed");
isLoading = false;
}
}, 1000);
}
}
}
第二种实现:当且仅当滑动到最后一项并且手指上拉时才执行上拉加载更多
需要配合onScrollStateChanged(RecyclerView recyclerView, int newState的使用,可以将代码改为:
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
Log.d("test", "StateChanged = " + newState);
if (newState == RecyclerView.SCROLL_STATE_IDLE && lastVisibleItemPosition + 1 == adapter.getItemCount()) {
Log.d("test", "loading executed");
boolean isRefreshing = swipeRefreshLayout.isRefreshing();
if (isRefreshing) {
adapter.notifyItemRemoved(adapter.getItemCount());
return;
}
if (!isLoading) {
isLoading = true;
handler.postDelayed(new Runnable() {
@Override
public void run() {
getData();
Log.d("test", "load more completed");
isLoading = false;
}
}, 1000);
}
}
}
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
Log.d("test", "onScrolled");
lastVisibleItemPosition = layoutManager.findLastVisibleItemPosition();
}
第三种是:每次滚动到最后一项都触发的加载更多:
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
int lastVisibleItemPosition = layoutManager.findLastVisibleItemPosition();
if (lastVisibleItemPosition + 1 == adapter.getItemCount()) {
Log.d("test", "loading executed");
boolean isRefreshing = swipeRefreshLayout.isRefreshing();
if (isRefreshing) {
adapter.notifyItemRemoved(adapter.getItemCount());
return;
}
if (!isLoading) {
isLoading = true;
handler.postDelayed(new Runnable() {
@Override
public void run() {
getData();
Log.d("test", "load more completed");
isLoading = false;
}
}, 1000);
}
}
}