在RecyclerView.Adapter中覆盖notifyItemChanged的animation

那么,我有一个适配器的RecyclerView,一切都很好。 ArrayList数据集中的项目正在定期更新。 所以项目和元素以及它们在列表中的位置都会改变。 这是通过简单的sorting和手动调用这些方法来实现的,无论什么时候发生:

// 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); 

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

我find了几个解决scheme:

 // disabling all animations recyclerView.getItemAnimator().setSupportsChangeAnimations(false); // or // setting the animation duration to zero, recyclerView.getItemAnimator().setChangeDuration(0); 

但是这两个都会在物品移动(被交换)时杀死animation。 我只是想重写一个animation,并保持所有这些魔术。 有没有办法做到这一点? 如果它重写ItemAnimator,有没有人有一个简单的例子?

提前致谢!

  • RecyclerView:获取位置并切换到活动
  • 使用setNestedScrollingEnabled(false)时如何避免阻止滚动?
  • 如何重叠LinearLayoutManager中的项目 - RecyclerView(如堆叠卡)
  • 嵌套RecyclerView自己滚动
  • StaggeredGridLayoutManagerdynamic更改spanCount RecylerView
  • RecyclerView中的滚动条颜色
  • RecyclerView GridLayoutManager具有全宽标题
  • “android:textIsSelectable =”true“不适用于RecyclerView中的TextView
  • 有一个专门的方法来禁用项目更改的animation:

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

    官方文档 。

    是的,我做到了。

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

     recyclerView.setItemAnimator(new MyItemAnimator()); 

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

     animateChangeImpl(final ChangeInfo changeInfo) { ... } 

    我们只需要find更改alpha值的方法调用。 find以下两行并删除.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() { ... } 

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

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

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

    尝试设置:

     mRecyclerview.setItemAnimator(null); 

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

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

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

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

     mRecyclerview.setHasFixedSize(true); 

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

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

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