如何获取Recyclerview/Layoutmanager中的Scrollposition?

How to get the Scrollposition in the Recyclerview/Layoutmanager?

如何获取 RecyclerviewLayoutmanager 中的滚动位置?

我可以通过添加一个 OnScrollListener 来测量滚动位置,但是当 Orientation 改变时 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;
            }
        });

你无法得到它,因为它并不真实存在。 LayoutManager 只知道屏幕上的视图,不知道之前的视图,它们的大小等

您可以使用滚动侦听器计算的数字不可靠,因为如果数据发生变化,RecyclerView 将进行新的布局计算并且不会尝试重新计算实际偏移量(您将收到onScroll(0, 0) 如果视图移动)。

RecyclerView 估计滚动条的这个值,您可以使用 View class.

中的相同方法

computeHorizontalScrollExtent

computeHorizontalScrollRange

computeHorizontalScrollOffset

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

你必须在

中阅读 scrollDy
public void onScrollStateChanged(RecyclerView recyclerView, int newState)

然后就可以得到recyclerView's的滚动位置

我来到这个问题只是想获取当前滚动到的项目位置索引。对于其他想要这样做的人,您可以使用以下内容:

LinearLayoutManager myLayoutManager = myRecyclerView.getLayoutManager();
int scrollPosition = myLayoutManager.findFirstVisibleItemPosition();

您还可以获得这些其他职位:

  • findLastVisibleItemPosition()
  • findFirstCompletelyVisibleItemPosition()
  • findLastCompletelyVisibleItemPosition()

感谢 对此的帮助。它还展示了如何保存和恢复滚动位置。

为了将来使用,如果您在同一个 activity 中的 Fragments 之间切换,而您要做的就是 保存滚动位置 recyclerview然后恢复recyclerview到相同的scroll-position,可以如下操作:

在您的 onStop()/onDestroyView()/onPause() 中,无论哪种回调更合适,请执行以下操作:

Parcelable recylerViewState = recyclerView.getLayoutManager().onSaveInstanceState();

并且在您的 onStart()/onCreateView()/onResume() 任何更合适的回调中,执行此操作:

recyclerView.getLayoutManager().onRestoreInstanceState(recylerViewState);

这样您就可以成功地将您的 recyclerView's 状态保持在 parcelable 并随时恢复它。

找到了解决 RecyclerView 中最后滚动位置的方法,并归功于 Suragch 解决方案... 声明一个全局可访问的 LinearLayoutManager 以便能够在内部方法中访问它... 每当调用 populateChatAdapter 方法时,如果第一次调用滚动到的位置将是最后发送的消息,并且如果用户滚动查看以前的消息并且再次调用方法以更新新消息,那么它们将保留他们最后滚动到位置...

LinearLayoutManager linearLayoutManager;
int lastScrollPosition = 0;
RecyclerView messages_recycler;

启动它们...

messages_recycler = findViewById(R.id.messages_recycler);
linearLayoutManager = new LinearLayoutManager(this);
linearLayoutManager.setStackFromEnd(true);
messages_recycler.setLayoutManager(linearLayoutManager);

关于您的填充适配器方法

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);
}

recyclerView.computeVerticalScrollOffset() 成功了。

要获得 ScroolPosition,试试这个:

  1. 您将需要这个:

        mLayoutManager = new LinearLayoutManager(getApplicationContext(), LinearLayoutManager.HORIZONTAL, false);
    
  2. 然后获取mLayoutManager的位置(像这样):

 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);
         }
});

有了这个 "pos" 你就得到了位置,从 0 开始。

   int pos = mLayoutManager.getPosition(v);