RecyclerView滚动到指定位置但不带动画

21

以前,当我想要滚动一个ListView到特定的位置时,我会使用

listView.setSelection(row);

ListView将会在没有任何动画的情况下滚动 - Android List View set default position without animation

现在,我想要在RecyclerView上达到相同的效果。我试图执行

((LinearLayoutManager)recyclerView.getLayoutManager()).scrollToPositionWithOffset(row, 0);

然而,有滚动动画,我希望避免使用它。

有没有办法我可以在程序中执行滚动而不使用动画?

这就是我所指的动画 - https://youtu.be/OKsUKwBLoks

请注意,我已经尝试了以下方法。所有这些都会生成动画。

  • scrollToPositionWithOffset
  • smoothScrollToPosition
  • scrollToPosition

你发布的视频展示了一个项目插入动画,与滚动动画无关。 - BladeCoder
@BladeCoder 抱歉,稍后会修改视频以避免混淆。 - Cheok Yan Cheng
是一个错误。动画是由加法操作引起的,而不是滚动操作本身。因此,这本身就是一个无效的问题。对造成的混淆感到抱歉。 - Cheok Yan Cheng
1
这是一个有效的问题。ScrollToPosition()触发了DefaultItemAnimator中的AnimateAdd()。应该重新打开。 - nyconing
5个回答

16

我知道我回答有点晚,但它可能会对其他人有所帮助。 尝试以下方法(至少我在使用时无法看到任何动画效果):

Kotlin:

    //-- Immediately jump to the position in RecyclerView without delay or animation.
    mRecyclerView.viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener {
        override fun onGlobalLayout() {
            mRecyclerView.scrollToPosition(position)
            mRecyclerView.viewTreeObserver.removeOnGlobalLayoutListener(this)
        }
    })

Java:

mRecyclerView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
        @Override
        public void onGlobalLayout() {
            mRecyclerView.scrollToPosition(position);
            mRecyclerView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
        }
});

1
非常好用,谢谢。 - Vikash Sharma
其他人现在在工作。这对我的情况有效。 - Parth Patel

2
在你的layout.xml文件中添加这一行代码。
android:overScrollMode="never"

编辑:

滚动RecycleView的另一种方法

recyclerView.smoothScrollToPosition(position);

我以为android:overScrollMode只适用于ScrollView?我在RecyclerView上进行了测试,但没有任何区别。滚动动画仍然存在。 - Cheok Yan Cheng
@CheokYanCheng 我编辑了我的答案,添加了另一种滚动RecycleView的方法,请尝试。 - Context
6
无效。平滑滚动会执行滚动动画。 - Cheok Yan Cheng

2

您可以使用以下方法进行无动画滚动:

recyclerView.scrollToPosition(position)

1

当您同时调用 notifyItemInserted()scrollToPosition() 时,会很容易出现这种情况。

动画由 RecyclerView 的默认项目动画类 DefaultItemAnimator 引起。

我发现 Youtube视频 其他人重现了这个问题。

我也有解决方案:

  • 首先使用 scrollToPosition() 滚动到最后位置。
  • 其次,等待一段时间让布局管理器完成滚动。
  • 第三,将新项目添加到适配器数据集中。
  • 最后,现在调用 notifyItemInserted()scrollToPosition()

我有一个编程示例,但是用编写的,但是使用lambda表达式时与相同。如果您需要在Adapter内访问RecyclerView,您可能需要查看Adapter.onAttachedToRecyclerView()

if (Adapter.ListData.Count > 2) Adapter.RecyclerView.ScrollToPosition(Adapter.ListData.Count - 1);
Adapter.RecyclerView.PostDelayed(() =>
{
    Adapter.ListData.Add(new ItemSimplyfiedAdapter.Standard
    {
       //Some new item inserting into data set.
    });
    Adapter.NotifyItemInserted(Adapter.ListData.Count - 1);
    Adapter.RecyclerView?.ScrollToPosition(Adapter.ListData.Count - 1);
}, 100);

0

正如评论中@nyconing所说,这种行为是由附加到回收站视图的默认ItemAnimator引起的。只需将其删除即可!

    recyclerView.setItemAnimator(null);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接