在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