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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 08:15:11  来源:igfitidea点击:

How to get the Scrollposition in the Recyclerview/Layoutmanager?

javaandroidandroid-recyclerview

提问by seb

How to get the scrollposition in Recyclerviewor the Layoutmanager?

如何在Recyclerview或 中获取滚动位置Layoutmanager

I can measure the scrollposition by adding an OnScrollListener, but when the Orientation changes scrollDyis 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. LayoutManageronly 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, RecyclerViewwill 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 Viewclass.

RecyclerView 估计滚动条的这个值,你可以使用View类中的相同方法。

computeHorizontalScrollExtent

computeHorizontalScrollExtent

computeHorizontalScrollRange

computeHorizontalScrollRange

computeHorizontalScrollOffset

computeHorizontalScrollOffset

These methods have their vertical counterparts as well.

这些方法也有它们的垂直对应物。

回答by paju_man

You have to read scrollDyin

你必须读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 Fragmentswithin the same activityand all you want to do is save scroll-positionfor recyclerviewand then restore recyclerviewto 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'sstate in a parcelableand restore it whenever you want.

通过这种方式,您可以成功地将recyclerView's状态保持在 aparcelable并随时恢复。

回答by Von Neumann

Found a work around to getting last scrolled position within the RecyclerViewwith credits to Suragchsolution... Declare a globally accessible LinearLayoutManagerso a to be able to access it within inner methods... When ever the populateChatAdaptermethod 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积分...声明一个全局可访问的,以便能够在内部方法中访问它...每当调用该方法时,如果它是第一次调用滚动到位置将是最后发送的消息,如果用户已经滚动查看以前的消息并再次调用方法来更新新消息,那么他们将保留上次滚动到的位置...LinearLayoutManagerpopulateChatAdapter

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()诀窍。