【问题标题】:Override animation for notifyItemChanged in RecyclerView.Adapter覆盖 RecyclerView.Adapter 中 notifyItemChanged 的​​动画
【发布时间】:2020-08-16 16:29:06
【问题描述】:

嗯,我有一个带有适配器的 RecyclerView,一切正常。 ArrayList 数据集中的项目会定期更新。因此项目及其元素以及它们在列表中的位置会发生变化。这是通过简单的排序并在发生事情时手动调用这些方法来实现的:

// swapping two items
Collections.swap(items, i, j);
itemsAdapter.notifyItemMoved(i, j);

// adding a new one
itemAdapter.notifyItemInserted(items.size());

// when updating valus
itemAdapter.notifyItemChanged(i);

后者,是我痛苦的原因。每次更新项目时,都会触发一点“闪烁”动画。

我为此找到了几个解决方案:

// disabling all animations
recyclerView.getItemAnimator().setSupportsChangeAnimations(false);

// or

// setting the animation duration to zero,
recyclerView.getItemAnimator().setChangeDuration(0);

但是当项目移动(被交换)时,这两个都会终止动画。我只想覆盖一个动画并保留所有这些魔法。有没有办法做到这一点?如果它覆盖 ItemAnimator,有没有人有一个简单的例子?

提前致谢!

【问题讨论】:

  • 您找到解决方案了吗?我尝试使用 .setSupportsChangeAnimation(false),但我仍然使用 notifyItemChanged 眨眼。

标签: android android-recyclerview


【解决方案1】:

有一种专门的方法可以禁用仅更改项目的动画:

((SimpleItemAnimator) myRecyclerView.getItemAnimator()).setSupportsChangeAnimations(false);

Official docs.

【讨论】:

  • 我想在调用 notifyItemChanged() 时移除内置的“dim”动画——这非常有效。使用 AppCompat-v7:25.3.1
  • 这不适用于项目中定义的约束布局。一些项目稍微移动到不同的位置,然后再次正常显示。仍然无法按预期工作
  • 奇怪但动画不断出现。
  • 我的用例的完美答案。非常感谢。
【解决方案2】:

是的,我做到了。

首先,获取DefaultItemAnimator的源码。获取代码并在您的项目中创建一个名为 MyItemAnimator 的类。然后,将 ItemAnimator 设置为修改后的 MyItemAnimator 的新实例,如下所示:

recyclerView.setItemAnimator(new MyItemAnimator());

现在,进入新类的源代码并找到方法

animateChangeImpl(final ChangeInfo changeInfo) { ... }

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

oldViewAnim.alpha(0).setListener(new VpaListenerAdapter() { ... }
newViewAnimation.translationX(0).translationY(0).setDuration(getChangeDuration()).alpha(1).setListener(new VpaListenerAdapter() { ... }

像这样

oldViewAnim.setListener(new VpaListenerAdapter() { ... }
newViewAnimation.translationX(0).translationY(0).setDuration(getChangeDuration()).setListener(new VpaListenerAdapter() { ... }

【讨论】:

【解决方案3】:

尝试设置:

mRecyclerview.setItemAnimator(null);

【讨论】:

    【解决方案4】:

    Kotlin 版本的@Pablo A. Martínez 答案:

    (recyclerView.itemAnimator as SimpleItemAnimator).supportsChangeAnimations = false
    

    【讨论】:

    • (recyclerView.itemAnimator as SimpleItemAnimator).supportsChangeAnimations = false
    【解决方案5】:

    如果你只是修改Recyclerview的数据意味着没有添加或删除项目,那么你应该添加这一行。

    mRecyclerview.setHasFixedSize(true); 
    

    这样recyclerview就会知道大小没有变化之后你就可以申请了

    ((SimpleItemAnimator) mRecyclerview.getItemAnimator()).setSupportsChangeAnimations(false);
    

    这样动画就会消失,代码会像魅力一样工作:)

    【讨论】:

      【解决方案6】:

      Alex 的回答略有不同。

      我没有完全移除 alpha 变化,而是减少了它。唯一需要的更改是:

              //changed alpha from 0
              ViewCompat.setAlpha(newHolder.itemView, 0.5f);
      

              //changed alpha from 0
              oldViewAnim.alpha(0.5f).setListener(new VpaListenerAdapter() {
      

      在这两种情况下,将 0 更改为 0.5 这具有消除与 alpha 完全为 0 相关的闪烁的效果,但保持项目更改动画的变形质量。

      【讨论】:

        【解决方案7】:

        在我的例子中,recyclerview 占据了工具栏下方的所有空间。我所做的只是将 recyclerview 的 layout_height 从 wrap_content 更改为 match_parent 并且闪烁消失了。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-04-09
          • 1970-01-01
          • 2016-07-12
          相关资源
          最近更新 更多