问题
recyclerview comes with its own scroll listener having below methods :
void onScrollStateChanged(RecyclerView recyclerView, int newState)
Callback method to be invoked when RecyclerView's scroll state changes.
void onScrolled(RecyclerView recyclerView, int dx, int dy)
Callback method to be invoked when the RecyclerView has been scrolled.
Is there any way to trigger loader to load more data when scroll reaches end of the list?
I have implemented this way:
@Override
public void onBindViewHolder(ViewHolder viewHolder, int i) {
GenerItem generItem=generItems.get(i);
Log.d("TAG","position "+i);
if(i==generItems.size()-1)
((GenerSearchActivity)mContext).onScroll(i);
viewHolder.bindValues(generItem);
}
here onScroll() in activity will trigger the loader to load more data. What is the best way please suggest.
回答1:
Here's a scroll listener which implements load more and quick return pattern:
public abstract class HidingScrollListener extends RecyclerView.OnScrollListener {
private static final float HIDE_THRESHOLD = 10;
private static final float SHOW_THRESHOLD = 70;
private int mToolbarOffset = 0;
private boolean mControlsVisible = true;
private int mToolbarHeight;
private int mTotalScrolledDistance;
private int previousTotal = 0;
private boolean loading = true;
private int visibleThreshold = 4;
int firstVisibleItem, visibleItemCount, totalItemCount;
private LinearLayoutManager layoutManager;
public HidingScrollListener(Context context, LinearLayoutManager layoutManager) {
mToolbarHeight = Tools.getFooterHeight(context);
this.layoutManager = layoutManager;
}
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
if (newState == RecyclerView.SCROLL_STATE_IDLE) {
if (mTotalScrolledDistance < mToolbarHeight) {
setVisible();
}
else {
if (mControlsVisible) {
if (mToolbarOffset > HIDE_THRESHOLD) {
setInvisible();
}
else {
setVisible();
}
}
else {
if ((mToolbarHeight - mToolbarOffset) > SHOW_THRESHOLD) {
setVisible();
}
else {
setInvisible();
}
}
}
}
}
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
clipToolbarOffset();
onMoved(mToolbarOffset);
if ((mToolbarOffset < mToolbarHeight && dy > 0) || (mToolbarOffset > 0 && dy < 0)) {
mToolbarOffset += dy;
}
if (mTotalScrolledDistance < 0) {
mTotalScrolledDistance = 0;
}
else {
mTotalScrolledDistance += dy;
}
// for load more
visibleItemCount = recyclerView.getChildCount();
totalItemCount = layoutManager.getItemCount();
firstVisibleItem = layoutManager.findFirstVisibleItemPosition();
if (loading) {
if (totalItemCount > previousTotal) {
loading = false;
previousTotal = totalItemCount;
}
}
if (!loading && (totalItemCount - visibleItemCount) <= (firstVisibleItem + visibleThreshold)) {
// End has been reached
// Do something
loading = true;
onLoadMore();
}
}
private void clipToolbarOffset() {
if (mToolbarOffset > mToolbarHeight) {
mToolbarOffset = mToolbarHeight;
}
else if (mToolbarOffset < 0) {
mToolbarOffset = 0;
}
}
private void setVisible() {
if (mToolbarOffset > 0) {
onShow();
mToolbarOffset = 0;
}
mControlsVisible = true;
}
private void setInvisible() {
if (mToolbarOffset < mToolbarHeight) {
onHide();
mToolbarOffset = mToolbarHeight;
}
mControlsVisible = false;
}
public abstract void onMoved(int distance);
public abstract void onShow();
public abstract void onHide();
public abstract void onLoadMore();
}
And it's implementation is below:
HidingScrollListener scrollListener = new HidingScrollListener(activity, manager) {
@Override
public void onMoved(int distance) {
}
@Override
public void onShow() {
}
@Override
public void onHide() {
}
@Override
public void onLoadMore() {
// you can do your pagination here.
}
};
mRecyclerView.addOnScrollListener(scrollListener);
来源:https://stackoverflow.com/questions/32955146/how-to-implement-pagination-in-recyclerview-on-scroll