java - 使用itemTouchViewer在Recyclerview中拖放不影响动画
问题描述
我在适配器类中实现 onDragDrop 方法。
public boolean onDragDrop(int fromPosition, int toPosition) {
Collections.swap(list, fromPosition, toPosition);
notifyItemMoved(fromPosition, toPosition);
if (fromPosition < toPosition) {
notifyItemRangeChanged(fromPosition, list.size());
} else {
notifyItemRangeChanged(toPosition, list.size());
}
return true;
}
我面临的问题是在实现 onDragDrop 方法时,动画效果不好;在被替换之前有一丝元素。我知道对于拖放,只需 notifyItemMoved 方法就足够了,并且动画是完美的。我实现 notifyItemRangeChanged 的原因是拖放后,我希望数据得到刷新。
我浏览了很多 StackOverflow 帖子并尝试实施这些建议,但没有任何效果。谢谢你的帮助。
解决方案
尝试在您的notifyItemRangeChanged()
调用中添加第三个参数。它实际上可以是任何对象,但我推荐它,Boolean.FALSE
因为它不会占用任何额外的内存,并且因为“假”和“不要运行我不想要的动画”是一些相关的概念。
if (fromPosition < toPosition) {
notifyItemRangeChanged(fromPosition, list.size(), Boolean.FALSE);
} else {
notifyItemRangeChanged(toPosition, list.size(), Boolean.FALSE);
}
这应该起作用的原因与当您通知适配器项目已更改时整个 RecyclerView 系统所做的事情有关。该过程的一部分涉及DefaultItemAnimator
,它必须决定是否重用旧的 ViewHolder 实例。你想要这个重复使用,但你没有得到它。
当您将第三个参数传递给 时notifyItemRangeChanged()
,该第三个参数作为“有效负载”在系统中传递。DefaultItemAnimator
是接收这个payload的系统的一部分,它根据这个payload是否存在来决定是否重用ViewHolders。
@Override public boolean canReuseUpdatedViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, @NonNull List<Object> payloads) { return !payloads.isEmpty() || super.canReuseUpdatedViewHolder(viewHolder, payloads); }
在您当前的代码中,没有有效负载,因此不会重复使用 ViewHolders。这会导致“旧” ViewHolder 淡出和“新” ViewHolder 淡入的动画,看起来非常像闪烁。
当你添加第三个参数时,突然有一个有效载荷。同样,有效载荷是什么并不重要,只要它存在即可。现在您的 ViewHolder 可以重复使用,因此没有淡入/淡出动画。
推荐阅读
- excel - 将多个 Column 映射并垂直转置到同一行中的同一 ID
- c++ - 初始化对象和赋值给对象的区别
- php - 具有纵横比的裁剪图像不考虑上下文
- c - 如何从主函数中的结构访问变量
- java - 选修的
findByUsername(String userName) create me error creation bean with name - php - 在同一台服务器上使用 PHP 创建 TMUX 实例
- python - Call async method from sync callback in Python
- python - matplotlib 中的交互式绘图和放大
- laravel - 如何使用单击事件导航到另一个带有参数的 vue 路由
- javascript - 为什么javascript对象解构不起作用?