简体   繁体   English

移动可观察项目时如何禁用recyclerview滚动

[英]How to disable recyclerview scrolling when observable item gets moved

When I have first recycler view item on position 0 and then lets say 10 items get inserted on position 0 making first one go to position 10 recycler view scrolls to position 10. How to disable this functionality making recycler view stay on top? When I have first recycler view item on position 0 and then lets say 10 items get inserted on position 0 making first one go to position 10 recycler view scrolls to position 10. How to disable this functionality making recycler view stay on top?

I have a possible answer below, but it has disadvatanges.我在下面有一个可能的答案,但它有缺点。 With this aproach recyclerview indeed will scroll to the top but only after scrolling to the end.使用这种方法,recyclerview 确实会滚动到顶部,但只有在滚动到末尾之后才会滚动。 And it's kinda annoying.这有点烦人。 Any one knows how to make it stay on top without going to the end?有谁知道如何让它保持在顶部而不到最后?

I had the exact same problem - for me when my LiveData<List<Item>> which my recyclerview was displaying updated in such a way that the first item changed positions, it would always scroll to the new position of that item (but not if any other item other than the first one was moved).我遇到了完全相同的问题 - 对我来说,当我的recyclerview视图显示的LiveData<List<Item>>以这样的方式更新时,第一个项目改变了位置,它总是会滚动到该项目的新 position (但如果除第一个项目外的任何其他项目都已移动)。 I found a relatively simple solution.我找到了一个相对简单的解决方案。 In the fragment with the recylcerview which displays your LiveData , you presumably have code something like this:在显示您的recylcerview的带有LiveDatafragment中,您可能有如下代码:

myViewModel.getAllItems().observe(getViewLifeCycleOwner(), items -> {
   myAdapter.setItems(items);
});

To stop it from scrolling when the first item is moved, simply add these two lines either side of the setItems() method:要在移动第一个项目时停止滚动,只需在setItems()方法的任一侧添加这两行:

myViewModel.getAllItems().observe(getViewLifeCycleOwner(), items -> {
   Parcelable recyclerViewState = myRecyclerView.getLayoutManager().onSaveInstanceState();
   adapter.setItems(slItems);
   myRecyclerView.getLayoutManager().onRestoreInstanceState(recyclerViewState);
});

This seems to restore the original scroll position if it was going to change it, making the UI stay at whatever scroll position it was at before the change occurred without any perceptible movement.如果要更改它,这似乎恢复了原始滚动 position,使 UI 保持在更改发生之前的任何滚动 position 没有任何可察觉的移动。

One workaround is to register AdapterDataObserver on your recycler view adapter overriding onItemRangeInserted method as in the following code.一种解决方法是在您的回收器视图适配器上注册 AdapterDataObserver,覆盖 onItemRangeInserted 方法,如下面的代码所示。 When something gets inserted on position 0 it automatically triggers layoutManager to scroll to start of the list.当在 position 0 上插入某些内容时,它会自动触发 layoutManager 滚动到列表的开头。

With this aproach recyclerview indeed will scroll to the top but only after scrolling to the end.使用这种方法,recyclerview 确实会滚动到顶部,但只有在滚动到末尾之后才会滚动。 And it's kinda annoying.这有点烦人。 Any one knows how to make it stay on top without going to the end?有谁知道如何让它保持在顶部而不到最后?

adapter?.registerAdapterDataObserver(object: RecyclerView.AdapterDataObserver() {
                override fun onItemRangeInserted(positionStart: Int, itemCount: Int) {
                    if (positionStart == 0) layoutManager?.scrollToPosition(0)
                }
            })

Inspired by Константин Семочкин I found an easy solution:受Константин Семочкин的启发,我找到了一个简单的解决方案:

listAdapter.registerAdapterDataObserver(object : RecyclerView.AdapterDataObserver() {
    // Prevent the list from scrolling when an item position change
    override fun onItemRangeMoved(fromPosition: Int, toPosition: Int, itemCount: Int) {
        lifecycleScope.launch {
            binding.manutenzioniList.scrollToPosition(fromPosition)
        }
    }
})

Every time that an item is moved the list moves back to the previous position.每次移动项目时,列表都会移回之前的 position。 Note that the list do no start the smooth scroll at all, so there isn't any annoying scroll back and forth请注意,列表根本不会启动平滑滚动,因此没有任何烦人的来回滚动

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM