我正在适配器类中实现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帖子并尝试实现建议,但是没有任何效果。感谢您的帮助。
答案 0 :(得分:1)
尝试在您的notifyItemRangeChanged()
调用中添加第三个参数。它实际上可以是任何对象,但是我建议使用Boolean.FALSE
,因为它不会占用任何额外的内存,并且因为“ false”和“不要运行我不想要的动画”是一些相关概念。
if (fromPosition < toPosition) {
notifyItemRangeChanged(fromPosition, list.size(), Boolean.FALSE);
} else {
notifyItemRangeChanged(toPosition, list.size(), Boolean.FALSE);
}
当您通知适配器项目已更改时,此工作正常的原因与整个RecyclerView系统的工作有关。该过程的一部分涉及DefaultItemAnimator
,它必须决定是否重新使用旧的ViewHolder实例。您想要这种重复使用,但没有得到。
当您将第三个参数传递给notifyItemRangeChanged()
时,该第三个参数将作为“有效负载”在系统中传递。 DefaultItemAnimator
是接收此有效负载的系统的一部分,它根据此有效负载是否存在来决定是否重用ViewHolders。
@Override public boolean canReuseUpdatedViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, @NonNull List<Object> payloads) { return !payloads.isEmpty() || super.canReuseUpdatedViewHolder(viewHolder, payloads); }
在您当前的代码中,没有有效负载,因此ViewHolders不会被重复使用。这会导致“旧” ViewHolder淡出和“新” ViewHolder淡入的动画,看起来非常像闪烁。
添加第三个参数时,突然有一个有效载荷。同样,有效载荷什么无关紧要,只是它根本就存在。现在,您的ViewHolder可以重新使用了,因此没有淡入/淡出动画。