如何实现RecyclerView的ItemAnimator来禁用notifyItemChanged的动画

Ken*_*nny 59 animation android android-recyclerview

在我的项目中,我需要禁用RecyclerViewwhile 的"更改"动画notifyItemChanged.

我在源头调查RecyclerView并被覆盖android.support.v7.widget.DefaultItemAnimator如下:

private static  class ItemAnimator extends DefaultItemAnimator
{
    @Override
    public boolean animateChange(RecyclerView.ViewHolder oldHolder, RecyclerView.ViewHolder newHolder, int fromX, int fromY, int toX, int toY) {
        if(oldHolder != null)
        {
            oldHolder.itemView.setVisibility(View.INVISIBLE);
            dispatchChangeFinished(oldHolder, true);
        }

        if(newHolder != null)
        {
            dispatchChangeFinished(newHolder, false);
        }

        return false;
    }
}
Run Code Online (Sandbox Code Playgroud)

但我不确定我是否符合Google文档的规范: RecyclerView.ItemAnimator.animateChange

根据我的理解源代码,如果我没有正确覆盖方法,oldHolder 将不会被回收.

请帮我弄清楚如何以animateChange正确的方式覆盖.

Ken*_*nny 112

我找到了正确的解决方案来删除animateChange.

这很简单.谷歌已实施该功能.

((SimpleItemAnimator) RecyclerView.getItemAnimator()).setSupportsChangeAnimations(false);
Run Code Online (Sandbox Code Playgroud)

文档:setSupportsChangeAnimations

  • 它也在*DefaultItemAnimator*中定义,您可以这样做:`((DefaultItemAnimator)recyclerView.getItemAnimator()).setSupportsChangeAnimations(false);` (2认同)
  • 这对我来说破坏了 DiffUtil.Result.dispatchChanges 的项目移动动画。 (2认同)

Sae*_*nic 51

我有同样的问题.当调用notifyItemChanged时,有一个红色覆盖闪烁.在试验你的代码后,我终于通过简单的调用删除了默认的Animator

recyclerView.setItemAnimator(null);
Run Code Online (Sandbox Code Playgroud)

在RecyclerView上.

  • recyclerView.setItemAnimator(NULL); 将删除RecyclerView的所有动画.我只想删除animateChange.谢谢您的回答. (9认同)

Shu*_*Shu 8

@Kenny的答案不再起作用,因为谷歌删除方法setSupportsChangeAnimations()(但为什么?)在支持库23.1.0中.

在某些情况下,setChangeDuration(0)可以作为解决方法.

@edit我建议使用类似的东西:

  RecyclerView.ItemAnimator animator = recyclerView.getItemAnimator();
        if (animator instanceof SimpleItemAnimator) {
            ((SimpleItemAnimator) animator).setSupportsChangeAnimations(false);
        }
Run Code Online (Sandbox Code Playgroud)


Tou*_*hid 7

如果有人像我一样绊倒:
不知何故setSupportsChangeAnimations(false)对我不起作用,但recyclerView.getItemAnimator().setChangeDuration(0)刚刚很好地删除了动画。


Ale*_*lex 5

如果找到了解决方案,对于想要保留 DefaultItemAnimator 给出的所有动画但摆脱每次更新视图时发生的“闪烁”动画的每个人。

首先,获取 DefaultItemAnimator 的源代码。在您的项目中创建一个同名的类。

其次,将 ItemAnimator 设置为修改后的 DefaultItemAnimator 的新实例,如下所示:

recyclerView.setItemAnimator(new MyItemAnimator());
Run Code Online (Sandbox Code Playgroud)

然后,进入新的类源代码并找到该方法

animateChangeImpl(final ChangeInfo changeInfo) { ... }
Run Code Online (Sandbox Code Playgroud)

现在,我们只需定位更改 alpha 值的方法调用。找到以下两行并删除 .alpha(0) 和 .alpha(1)

oldViewAnim.alpha(0).setListener(new VpaListenerAdapter() { ... }
newViewAnimation.translationX(0).translationY(0).setDuration(getChangeDuration()).alpha(1).setListener(new VpaListenerAdapter() { ... }
Run Code Online (Sandbox Code Playgroud)

像这样

oldViewAnim.setListener(new VpaListenerAdapter() { ... }
newViewAnimation.translationX(0).translationY(0).setDuration(getChangeDuration()).setListener(new VpaListenerAdapter() { ... }
Run Code Online (Sandbox Code Playgroud)