情景描述
我們使用列表顯示數據時,通常都會遇到需要加載更多數據的情況,比如列表即將滾動到底部時,我們就需要進行新的數據的獲取及填充。本篇博客介紹的是:自定義RecyclerView,添加即將滾動到底部的回調,方便實現加載更多功能。
代碼
/**
* Add the callback of reaching bottom into RecyclerView
* Support three LayoutManager(Linear、Grid、StaggeredGrid)
* Created by wiky on 2016/3/26.
*/
public class RBCallbkRecyclerView extends RecyclerView {
private OnReachBottomListener onReachBottomListener;
private boolean isInTheBottom = false;
/**
* reachBottomRow = 1;(default)
* mean : when the lastVisibleRow is lastRow , call the onReachBottom();
* reachBottomRow = 2;
* mean : when the lastVisibleRow is Penultimate Row , call the onReachBottom();
* And so on
*/
private int reachBottomRow = 1;
public RBCallbkRecyclerView(Context context) {
super(context);
}
public RBCallbkRecyclerView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public RBCallbkRecyclerView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
public void onScrolled(int dx, int dy) {
super.onScrolled(dx, dy);
if (onReachBottomListener != null) {
LayoutManager layoutManager = getLayoutManager();
if (layoutManager == null) { //it maybe unnecessary
throw new RuntimeException("LayoutManager is null,Please check it!");
}
Adapter adapter = getAdapter();
if (adapter == null) { //it maybe unnecessary
throw new RuntimeException("Adapter is null,Please check it!");
}
boolean isReachBottom = false;
//is GridLayoutManager
if (layoutManager instanceof GridLayoutManager) {
GridLayoutManager gridLayoutManager = (GridLayoutManager) layoutManager;
int rowCount = adapter.getItemCount() / gridLayoutManager.getSpanCount();
int lastVisibleRowPosition = gridLayoutManager.findLastVisibleItemPosition() / gridLayoutManager.getSpanCount();
isReachBottom = (lastVisibleRowPosition >= rowCount - reachBottomRow);
}
//is LinearLayoutManager
else if (layoutManager instanceof LinearLayoutManager) {
int lastVisibleItemPosition = ((LinearLayoutManager) layoutManager).findLastVisibleItemPosition();
int rowCount = adapter.getItemCount();
if (reachBottomRow > rowCount)
reachBottomRow = 1;
isReachBottom = (lastVisibleItemPosition >= rowCount - reachBottomRow);
}
//is StaggeredGridLayoutManager
else if (layoutManager instanceof StaggeredGridLayoutManager) {
StaggeredGridLayoutManager staggeredGridLayoutManager = (StaggeredGridLayoutManager) layoutManager;
int spanCount = staggeredGridLayoutManager.getSpanCount();
int[] into = new int[spanCount];
int[] eachSpanListVisibleItemPosition = staggeredGridLayoutManager.findLastVisibleItemPositions(into);
for (int i = 0; i < spanCount; i++) {
if (eachSpanListVisibleItemPosition[i] > adapter.getItemCount() - reachBottomRow * spanCount) {
isReachBottom = true;
break;
}
}
}
if (!isReachBottom) {
isInTheBottom = false;
} else if (!isInTheBottom) {
onReachBottomListener.onReachBottom();
isInTheBottom = true;
Log.d("RBCallbkRecyclerView", "onReachBottom");
}
}
}
public void setReachBottomRow(int reachBottomRow) {
if (reachBottomRow < 1)
reachBottomRow = 1;
this.reachBottomRow = reachBottomRow;
}
public interface OnReachBottomListener {
void onReachBottom();
}
public void setOnReachBottomListener(OnReachBottomListener onReachBottomListener) {
this.onReachBottomListener = onReachBottomListener;
}
}
使用
基礎使用和RecyclerView無差別
添加接口回調方法:
mRBCallbkRecyclerView.setOnReachBottomListener(new RBCallbkRecyclerView.OnReachBottomListener() {
@Override
public void onReachBottom() {
//即將到達幾部,進行加載更多操作
}
});
同時支持設置還剩X行數據時,即進行回調
mRBCallbkRecyclerView.setReachBottomRow(1);//(默認)最後一行可見時,進行回調