重写循环视图。适配器中的 notifyItemChanged 动画

我有一个带适配器的回收视图,一切都很好。数组列表数据集中的项正在定期更新。因此,项目和它们的元素以及它们在列表中的位置都发生了变化。这是通过简单的排序和手动调用这些方法实现的,无论何时发生:

// 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,有人有一个简单的例子吗?

先谢谢你!

47762 次浏览

是的,没错。

首先,获取 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() { ... }

亚历克斯的回答略有不同。

我没有完全去除 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,但保持项目的变形质量更改动画。

有一个专门的方法来禁用只是项目更改的动画:

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

官方文件。

在我的案例中,回收视图占据了工具栏下面的所有空间。我所做的仅仅是改变了布局-高度的回收视图从包装-内容匹配-父和眨眼消失。

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

mRecyclerview.setHasFixedSize(true);

因此,回收站将获得知道,有没有大小的变化之后,你可以申请

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

因此,动画将消失,代码将像魅力:)

试试设置:

mRecyclerview.setItemAnimator(null);

Kotlin 版本的 @ Pablo A. Martinez回答:

(recyclerView.itemAnimator as SimpleItemAnimator).supportsChangeAnimations = false