简体   繁体   English

如何在 Recyclerview/Layoutmanager 中获取 Scrollposition?

[英]How to get the Scrollposition in the Recyclerview/Layoutmanager?

How to get the scrollposition in Recyclerview or the Layoutmanager ?如何在Recyclerview或 Layoutmanager 中获取滚动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;
            }
        });

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)您将收到onScroll(0, 0) )。

RecyclerView estimates this value for scrollbars, you can use the same methods from View class. RecyclerView 估计滚动条的这个值,您可以使用View类中的相同方法。

computeHorizontalScrollExtent

computeHorizontalScrollRange

computeHorizontalScrollOffset

These methods have their vertical counterparts as well.这些方法也有它们的垂直对应物。

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:为了将来使用,如果您在同一activity Fragments之间切换,并且您想要做的只是为recyclerview保存 scroll-position ,然后recyclerview恢复到相同的 scroll-position ,则可以执行以下操作:

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状态保持在可parcelable状态,并在需要时parcelable恢复。

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.它还展示了如何保存和恢复滚动位置。

recyclerView.computeVerticalScrollOffset()可以解决问题。

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...找到了一个解决方法来获得RecyclerView最后一个滚动位置,并归功于Suragch解决方案......声明一个全局可访问的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);
}

You have to read scrollDy in你必须阅读scrollDy

public void onScrollStateChanged(RecyclerView recyclerView, int newState)

then you can get recyclerView' s scroll position然后你可以得到recyclerView'的滚动位置

To get ScroolPosition try this:要获得 ScroolPosition 试试这个:

  1. You will need this:你会需要这个:

     mLayoutManager = new LinearLayoutManager(getApplicationContext(), LinearLayoutManager.HORIZONTAL, false);
  2. And then get the position of the mLayoutManager (like this):然后获取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); } });

With this "pos" you get the position, startin with the 0.有了这个“pos”,你就得到了位置,从 0 开始。

   int pos = mLayoutManager.getPosition(v);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何从RecyclerView.Adapter访问LayoutManager以获取scrollToPosition? - How to access LayoutManager from RecyclerView.Adapter to get scrollToPosition? 如何将 RecyclerView LayoutManager 从 List 更改为 Grid? - How to change RecyclerView LayoutManager from List to Grid? Android RecyclerView LayoutManager异常 - Android RecyclerView LayoutManager Exception 如何从RecyclerView的ItemDecoration类访问LayoutManager? - How to access the LayoutManager from the RecyclerView's ItemDecoration class? 如何在onBindviewholder中获取Layoutmanager状态,以便基于layoutmanager更新我的字段 - How to get Layoutmanager state in onBindviewholder so as to update my fields based on layoutmanager 为片段创建RecyclerView时LayoutManager和RecyclerView问题 - LayoutManager and RecyclerView Issues When Creating RecyclerView For Fragment 我如何使用LayoutManager来获得这样的布局? - How would I use LayoutManager to get a layout like this? RecyclerView、RecyclerView.Adapter和RecyclerView.LayoutManager在哪里声明? - Where to declare RecyclerView, RecyclerView.Adapter and RecyclerView.LayoutManager? 无法使用LayoutManager在RecyclerView中还原滚动位置 - Unable to Restore the Scroll Position in RecyclerView using LayoutManager 添加 RecyclerView Layoutmanager 时我的应用程序停止 - My app stopped when adding a RecyclerView Layoutmanager
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM