Java 如何在 Recyclerview/Layoutmanager 中获取 Scrollposition?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/29581782/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to get the Scrollposition in the Recyclerview/Layoutmanager?
提问by seb
How to get the scrollposition in Recyclerview
or the Layoutmanager
?
如何在Recyclerview
或 中获取滚动位置Layoutmanager
?
I can measure the scrollposition by adding an OnScrollListener
, but when the Orientation changes scrollDy
is 0.
我可以通过添加 来测量滚动位置OnScrollListener
,但是当方向更改scrollDy
为 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;
}
});
采纳答案by yigit
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.
你无法得到它,因为它实际上并不存在。LayoutManager
只知道屏幕上的视图,它不知道之前的视图,它们的大小等。
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
将进行新的布局计算并且不会尝试重新计算实际偏移量(您将收到onScroll(0, 0)
if 视图移动)。
RecyclerView estimates this value for scrollbars, you can use the same methods from View
class.
RecyclerView 估计滚动条的这个值,你可以使用View
类中的相同方法。
computeHorizontalScrollExtent
computeHorizontalScrollExtent
computeHorizontalScrollRange
computeHorizontalScrollRange
computeHorizontalScrollOffset
computeHorizontalScrollOffset
These methods have their vertical counterparts as well.
这些方法也有它们的垂直对应物。
回答by paju_man
You have to read scrollDy
in
你必须读scrollDy
进去
public void onScrollStateChanged(RecyclerView recyclerView, int newState)
then you can get recyclerView'
s scroll position
然后你可以得到recyclerView'
s 滚动位置
回答by Suragch
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()
findLastVisibleItemPosition()
findFirstCompletelyVisibleItemPosition()
findLastCompletelyVisibleItemPosition()
Thanks to this answerfor help with this. It also shows how to save and restore the scroll position.
感谢这个答案对此的帮助。它还展示了如何保存和恢复滚动位置。
回答by Shoaib Anwar
For future use, If you are switching between Fragments
within the same activity
and all you want to do is save scroll-positionfor recyclerview
and then restore recyclerview
to the same scroll-position, you can do as follows:
对于今后的使用,如果你之间切换Fragments
在同一个activity
和所有你想要做的是保存滚动位置的recyclerview
,然后恢复recyclerview
到相同的滚动位置,你可以做如下:
In your onStop()/onDestroyView()/onPause()
whatever callback is more appropriate, do this:
在您onStop()/onDestroyView()/onPause()
更合适的回调中,请执行以下操作:
Parcelable recylerViewState = recyclerView.getLayoutManager().onSaveInstanceState();
And In your onStart()/onCreateView()/onResume()
whatever callback is more appropriate, do this:
在您onStart()/onCreateView()/onResume()
更合适的回调中,请执行以下操作:
recyclerView.getLayoutManager().onRestoreInstanceState(recylerViewState);
This way you can successfully keep your recyclerView's
state in a parcelable
and restore it whenever you want.
通过这种方式,您可以成功地将recyclerView's
状态保持在 aparcelable
并随时恢复。
回答by Von Neumann
Found a work around to getting last scrolled position within the RecyclerView
with credits to Suragchsolution...
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...
找到了一种解决方法来获得Suragch解决方案中最后滚动位置的RecyclerView
积分...声明一个全局可访问的,以便能够在内部方法中访问它...每当调用该方法时,如果它是第一次调用滚动到位置将是最后发送的消息,如果用户已经滚动查看以前的消息并再次调用方法来更新新消息,那么他们将保留上次滚动到的位置...LinearLayoutManager
populateChatAdapter
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);
}
回答by AndroidDev
recyclerView.computeVerticalScrollOffset()
does the trick.
recyclerView.computeVerticalScrollOffset()
诀窍。