在RecyclerView.Adapter中覆盖notifyItemChanged的动画

Ale*_*lex 54 android android-recyclerview

好吧,我有一个带适配器的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);
Run Code Online (Sandbox Code Playgroud)

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

我找到了几个解决方案:

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

// or

// setting the animation duration to zero,
recyclerView.getItemAnimator().setChangeDuration(0);
Run Code Online (Sandbox Code Playgroud)

但是当项目移动(被交换)时,这两个都会杀死动画.我只想覆盖一个动画并保持所有这些魔力.有办法做到这一点吗?如果它超越了ItemAnimator,有没有人有一个简单的例子?

提前致谢!

Pab*_*nez 96

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

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

官方文档.

  • 我的用例的完美答案。非常感谢。 (2认同)

Ale*_*lex 22

是的,我做到了.

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

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)

  • 哈克却发现了.链接到支持lib v7源https://android.googlesource.com/platform/frameworks/support/+/refs/heads/master/v7/recyclerview/src/android/support/v7/widget/DefaultItemAnimator.java (2认同)

box*_*box 10

尝试设置:

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


MBH*_*MBH 8

Kotlin@PabloA.Martínez回答:

(recyclerView.itemAnimator as SimpleItemAnimator).supportsChangeAnimations = false
Run Code Online (Sandbox Code Playgroud)

  • (recyclerView.itemAnimator为SimpleItemAnimator).supportsChangeAnimations = false (2认同)

Key*_*ani 5

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

mRecyclerview.setHasFixedSize(true); 
Run Code Online (Sandbox Code Playgroud)

这样recyclerview就会知道尺寸没有变化,然后你就可以申请了

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

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