我正在和
RecyclerView
进行 GridLayoutManager
。我已经实现了项目重新排序,因此用户可以使用 ItemTouchHelper
和 SimpleCallback
对项目重新排序。
但是重排序的时候存在死循环的问题。 为了更好地理解这个问题,请观看随附的视频:
重新排序的代码如下:
override fun onMove(
recyclerView: RecyclerView,
viewHolder: RecyclerView.ViewHolder,
target: RecyclerView.ViewHolder,
): Boolean {
val from = viewHolder.adapterPosition
val to = target.adapterPosition
val newSwitches = switches.toMutableList()
// 1
if (from < to) for (i in from until to) Collections.swap(newSwitches, i, i + 1)
else for (i in from downTo to + 1) Collections.swap(newSwitches, i, i - 1)
// Or 2
Collections.swap(newList, from, to)
setSwitches(newSwitches)
return true
}
在上面的代码中,方法 1 和 2 会导致无限循环问题,如视频所示。
当我打印
from
和 to
值来控制台时,它们就像:
from: 10, to: 11
from: 11, to: 10
from: 10, to: 11
from: 11, to: 10
and so on...
PS:我使用边到边在系统栏后面绘制,并使用
clipChildren="false"
和 clipToPadding="false"
对 RecyclerView 应用额外的填充。难道是因为这个才发的吗?
暂时禁用 RecyclerView 中的项目动画,看看在没有任何动画的情况下问题是否仍然存在。您可以通过在 RecyclerView 设置中设置以下行来完成此操作:
recyclerView.itemAnimator = null
确保您已重写 ItemTouchHelper.SimpleCallback 中的 canDropOver 方法并返回 true:
override fun canDropOver(
recyclerView: RecyclerView,
current: RecyclerView.ViewHolder,
target: RecyclerView.ViewHolder
): Boolean {
return true
}
考虑使用notifyItemMoved 来通知适配器有关项目移动的信息,而不是手动交换列表中的项目。这可确保适配器了解更改并相应地更新 UI。用这样的东西替换当前的交换逻辑:
notifyItemMoved(from, to)
如果问题仍然存在,提供有关 RecyclerView 设置的更多详细信息以及其余相关代码以供进一步分析可能会有所帮助。