Reputation: 4319
How to get the scrollposition in Recyclerview
or the Layoutmanager
?
I can measure the scrollposition by adding an OnScrollListener
, but when the Orientation changes scrollDy
is 0.
mRecyclerView.setOnScrollListener(new RecyclerView.OnScrollListener() {
int scrollDy = 0;
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
}
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
scrollDy += dy;
}
});
Upvotes: 54
Views: 90844
Reputation: 1
To get ScroolPosition try this:
You will need this:
mLayoutManager = new LinearLayoutManager(getApplicationContext(), LinearLayoutManager.HORIZONTAL, false);
And then get the position of the mLayoutManager (like this):
recyclerView
.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
int pos = mLayoutManager.getPosition(v);
RecyclerView.ViewHolder viewHolder = recyclerView.findViewHolderForAdapterPosition(pos);
}
});
With this "pos" you get the position, startin with the 0.
int pos = mLayoutManager.getPosition(v);
Upvotes: -4
Reputation: 51
Found a work around to getting last scrolled position within the RecyclerView
with credits to Suragch solution...
Declare a globally accessible LinearLayoutManager
so a to be able to access it within inner methods...
When ever the populateChatAdapter
method is called, if its the first call the scroll to position will be the last sent message and if the user had scrolled to view previous messages and method is called again to update new messages then they will retain their last scrolled to position...
LinearLayoutManager linearLayoutManager;
int lastScrollPosition = 0;
RecyclerView messages_recycler;
Initiate them...
messages_recycler = findViewById(R.id.messages_recycler);
linearLayoutManager = new LinearLayoutManager(this);
linearLayoutManager.setStackFromEnd(true);
messages_recycler.setLayoutManager(linearLayoutManager);
On your populate adapter method
private void populateChatAdapter(ObservableList<ChatMessages> msgs) {
if (lastScrollPosition==0) lastScrollPosition = msgs.size()-1;
ChatMessagesRecycler adapter = new ChatMessagesRecycler(msgs);
messages_recycler.setAdapter(adapter);
messages_recycler.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
lastScrollPosition = linearLayoutManager.findLastCompletelyVisibleItemPosition();
}
});
messages_recycler.scrollToPosition(lastScrollPosition);
}
Upvotes: 2
Reputation: 1625
For future use, If you are switching between Fragments
within the same activity
and all you want to do is save scroll-position for recyclerview
and then restore recyclerview
to the same scroll-position, you can do as follows:
In your onStop()/onDestroyView()/onPause()
whatever callback is more appropriate, do this:
Parcelable recylerViewState = recyclerView.getLayoutManager().onSaveInstanceState();
And In your onStart()/onCreateView()/onResume()
whatever callback is more appropriate, do this:
recyclerView.getLayoutManager().onRestoreInstanceState(recylerViewState);
This way you can successfully keep your recyclerView's
state in a parcelable
and restore it whenever you want.
Upvotes: 69
Reputation: 511586
I came to the question just wanting to get the item position index that is currently scrolled to. For others who want to do the same, you can use the following:
LinearLayoutManager myLayoutManager = myRecyclerView.getLayoutManager();
int scrollPosition = myLayoutManager.findFirstVisibleItemPosition();
You can also get these other positions:
findLastVisibleItemPosition()
findFirstCompletelyVisibleItemPosition()
findLastCompletelyVisibleItemPosition()
Thanks to this answer for help with this. It also shows how to save and restore the scroll position.
Upvotes: 44
Reputation: 38243
You cannot get it because it does not really exist. LayoutManager
only knows about the views on screen, it does not know the views before, what their size is etc.
The number you can count using the scroll listener is not reliable because if data changes, RecyclerView
will do a fresh layout calculation and will not try to re-calculate a real offset (you'll receive an onScroll(0, 0)
if views moved).
RecyclerView estimates this value for scrollbars, you can use the same methods from View
class.
computeHorizontalScrollExtent
computeHorizontalScrollRange
computeHorizontalScrollOffset
These methods have their vertical counterparts as well.
Upvotes: 55
Reputation: 1
You have to read scrollDy
in
public void onScrollStateChanged(RecyclerView recyclerView, int newState)
then you can get recyclerView'
s scroll position
Upvotes: 0