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
How to Use an Arrayadapter in Android of Custom Objects
How to Export Library to Jar in Android Studio
Disable Edittext Blinking Cursor
Toolbar Overlapping Below Status Bar
Is There a Simple Example of the Popupwindow Class Using Android V2.0
Run Code When Android App Is Closed/Sent to Background
How to Sign an APK with More Than One Certificate
How to Store an Integer Array in Sharedpreferences
Can't Stop the Ringing Alarm from Another Activity
How to Insert a SQLite Record with a Datetime Set to 'Now' in Android Application
Android Sdk 22 - Searchview Rendering Problems
Detect 7 Inch and 10 Inch Tablet Programmatically
Difference Between APK (.Apk) and App Bundle (.Aab)
What Is the Intent of the Methods Getitem and Getitemid in the Android Class Baseadapter
Calculate Text Size According to Width of Text Area
Android Studio - How to Make an Avd with Arm Instead of Haxm