在RecyclerView.Adapter中覆盖notifyItemChanged的动画

那么,我有一个适配器的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,有没有人有一个简单的例子?

提前致谢!

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

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

官方文档 。

是的,我做到了。

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

亚历克斯的答案略有差异。

我没有完全消除阿尔法变化,而是减少了阿尔法变化。 唯一需要改变的是:

  //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,但保持项目变形动画的变形质量。

尝试设置:

 mRecyclerview.setItemAnimator(null); 

在我的情况下,recyclerview占据了工具栏下面的所有空间。 我所做的只是把recyclerview的layout_height从wrap_content更改为match_parent,而且闪烁消失了。

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

 mRecyclerview.setHasFixedSize(true); 

因此,recyclerview将会知道您可以申请之后尺寸没有变化

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

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

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

 (mRecyclerview.getItemAnimator() as SimpleItemAnimator).supportsChangeAnimations = false