Detect When Recyclerview Reaches the Bottom Most Position While Scrolling

RecyclerView make network call when near the bottom

In your OnScrollListener calculate the difference between the bottom of the last child view in the Recycler view and the bottom of the Recycler view itself, if the last child view is close enough to the bottom of the recycler view you can make your network call.

mGridRecycler.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
View view = (View) recyclerView.getChildAt(recyclerView.getChildCount() - 1);
int difference = (view.getBottom() - (recyclerView.getHeight() + recyclerView.getScrollY()));

if (difference == 0) {
//Make network call here
}
}
});

difference == 0 means the absolute bottom when the Recycler view can't scroll anymore, you can change the condition to check when it 5px from the recycler view bottom difference == 5.

RecyclerView recognize when reaching end of scroll

Hello there add this to your code:

On your activity/fragment/where ever recyclerview is declared

RecyclerView rv; //Add your declare code (findViewById for example)
rv.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);

if (!recyclerView.canScrollHorizontally(1) ) {
Toast.makeText(ChatDetailsActivity.this,"endOfScroll",Toast.LENGTH_LONG).show();
//Implement button dim here. Example:
//mybutton.setAlpha(0.5f);

}
});

EDIT : Not sure if you want to scroll vertically or horizontally
change the word from Horizontally to Vertically in the if statement acording your need

Recyclerview indicates that reaches the last item

Thanks to Khemraj who give the tip for solution
because I have a recyclerview inside NestedScrollView and coordinator layout as parent for them

I have solved my problem like this:

public Disposable observeNestedScroll(LoadMoreListener listener) {
return RxNestedScrollView.scrollChangeEvents(nestedScrollView)
.subscribe(
viewScrollChangeEvent -> {
NestedScrollView nestedScrollView =(NestedScrollView) viewScrollChangeEvent.view();
if(nestedScrollView.getChildAt(nestedScrollView.getChildCount() - 1) != null) {
if ((viewScrollChangeEvent.scrollY() >= (nestedScrollView.getChildAt(nestedScrollView.getChildCount() - 1).getMeasuredHeight() - nestedScrollView.getMeasuredHeight())) &&
viewScrollChangeEvent.scrollY() > viewScrollChangeEvent.oldScrollY()) {
listener.onLoadMore();
}
}
});
}

How to detect when user have scrolled to the top most item in a RecyclerView

I have solved my question by myself. I used the code below instead

private boolean isUserScrolling = false;
private boolean isListGoingUp = true;

Then in the RecyclerView OnScrollListener

@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
//detect is the topmost item visible and is user scrolling? if true then only execute
if(newState == RecyclerView.SCROLL_STATE_DRAGGING){
isUserScrolling = true;
if(isListGoingUp){
//my recycler view is actually inverted so I have to write this condition instead
if(linearLayoutManager.findLastCompletelyVisibleItemPosition() + 1 == list.size()){
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
if(isListGoingUp) {
if (linearLayoutManager.findLastCompletelyVisibleItemPosition() + 1 == list.size()) {
Toast.makeText(getContext(),"exeute something", Toast.LENGTH_SHORT).show();
}
}
}
},50);
//waiting for 50ms because when scrolling down from top, the variable isListGoingUp is still true until the onScrolled method is executed
}
}
}
}

@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
if(isUserScrolling){
if(dy > 0){
//means user finger is moving up but the list is going down
isListGoingUp = false;
}
else{
//means user finger is moving down but the list is going up
isListGoingUp = true;
}
}
}

How programmatically know that recyclerview is scrolled position is bottom of recyclerview to execute following function

first / last visible child depends on the LayoutManager.
If you are using LinearLayoutManager or GridLayoutManager, you can use

int findFirstVisibleItemPosition();
int findFirstCompletelyVisibleItemPosition();
int findLastVisibleItemPosition();
int findLastCompletelyVisibleItemPosition();

For example:

GridLayoutManager layoutManager = ((GridLayoutManager)mRecyclerView.getLayoutManager());
int firstVisiblePosition = layoutManager.findLastCompletelyVisibleItemPosition();

For LinearLayoutManager, first/last depends on the adapter ordering. Don't query children from RecyclerView; LayoutManager may be prefered to layout more items than visible for caching.

Detect when the recyclerview has reached the top most position

As @Taseer Ahmad has suggested, this is the right answer. I am attaching the code snippet.

if (dy < 0) {
if ((recyclerView.layoutManager as LinearLayoutManager).findFirstCompletelyVisibleItemPosition() == 0) {
// load more messages
}
}


Related Topics



Leave a reply



Submit