Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/229.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 覆盖RecyclerView.Adapter中notifyItemChanged的动画_Android_Android Recyclerview - Fatal编程技术网

Android 覆盖RecyclerView.Adapter中notifyItemChanged的动画

Android 覆盖RecyclerView.Adapter中notifyItemChanged的动画,android,android-recyclerview,Android,Android Recyclerview,我有一个带适配器的RecyclerView,一切都很好。ArrayList数据集中的项正在定期更新。因此,项目及其元素以及它们在列表中的位置都会发生变化。这是通过简单的排序和手动调用这些方法实现的,无论何时发生: // swapping two items Collections.swap(items, i, j); itemsAdapter.notifyItemMoved(i, j); // adding a new one itemAdapter.notifyItemInserted(it

我有一个带适配器的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,有人举个简单的例子吗

提前谢谢

是的

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

recyclerView.setItemAnimator(new MyItemAnimator());
现在,进入新类源代码并找到该方法

animateChangeImpl(final ChangeInfo changeInfo) { ... }
我们只需找到改变alpha值的方法调用。找到以下两行并删除.alpha(0)和.alpha(1)

像这样

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

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

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

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

.

在我的例子中,recyclerview占据了工具栏下方的所有空间。我所做的只是将recyclerview的布局高度从包裹内容更改为与父项匹配,然后闪烁消失。

如果您只是修改recyclerview的数据,则不意味着添加或删除项目,则应添加此行

mRecyclerview.setHasFixedSize(true); 
这样,recyclerview就会知道,在您可以申请之后,大小没有变化

((SimpleItemAnimator) mRecyclerview.getItemAnimator()).setSupportsChangeAnimations(false);
这样,动画将消失,代码将像charm:)一样工作。

尝试设置:

mRecyclerview.setItemAnimator(null);

Kotlin答案版本:


你找到解决办法了吗。我尝试了.setSupportsChangeAnimation(false),但我仍然会在notifyItemChanged.Hacky上闪烁一次,但仍然正确。链接到支持lib v7 source当您在recyclerview项中显示/隐藏项时,此选项将删除fadeIn/out效果。我想在调用notifyItemChanged()时删除内置的“dim”动画--这非常有效。使用AppCompat-v7:25.3.1这不适用于项中定义的constraintLayout。一些项目稍微移动到不同的位置,然后再次正常显示。仍然不能按预期工作doesn不是真的工作-奇怪,但动画继续出现。完美回答我的用例。非常感谢。(recyclerView.itemAnimator作为SimpleItemAnimator)。SupportsAngeAnimations=false
((SimpleItemAnimator) mRecyclerview.getItemAnimator()).setSupportsChangeAnimations(false);
mRecyclerview.setItemAnimator(null);
(recyclerView.itemAnimator as SimpleItemAnimator).supportsChangeAnimations = false