我有一个RecyclerView设置,并且遇到了一个非常奇怪的问题,即在某些适配器更新期间,RecyclerView的各项相互重叠,好像它们在动画的中间停止了动画一样。此问题似乎主要发生在移动项目时,但有时删除具有相同的效果。我的初始设置是将AndroidX
beta01 ListAdapter
和Room用于我的应用程序数据库。我将简单地观察LiveData
并在observe方法中调用submitList()
我还应该注意,我添加了一个RecyclerView.AdapterDataObserver,它扩展了onItemMoved
并调用了layoutManager.moveToPosition(0)
以确保用户看到了更新。
此后,我尝试了许多故障排除步骤,其中包括:
moveToPosition(0)
代码手动列表比较方法:
private fun calculateListDiffs(model: List<T>) {
when {
model.size > list.size -> {
var i = 0
while (i < itemCount) {
if (!areItemsSame(list[i], model[i])) {
list.add(i, model[i])
notifyItemInserted(i)
} else
i++
}
}
model.size < list.size -> {
var i = 0
while (i < itemCount) {
when {
i >= model.size && !areItemsSame(list[i], model[model.size - 1]) -> {
list.removeAt(i)
notifyItemRemoved(i)
}
i < model.size && !areItemsSame(list[i], model[i]) -> {
list.removeAt(i)
notifyItemRemoved(i)
}
else -> i++
}
}
}
else -> {
run loop@{
for (i in 0 until itemCount) {
when {
!areItemsSame(list[i], model[i]) -> {
val pivot = model[i]
for (j in i until itemCount) {
if (areItemsSame(list[j], pivot)) {
list.removeAt(j)
list.add(i, pivot)
notifyItemMoved(j, i)
notifyItemChanged(i)
return@loop
}
}
}
!areContentsSame(list[i], model[i]) -> {
list[i] = model[i]
notifyItemChanged(i)
}
}
}
}
}
}
}
问题仍然存在,经过所有测试之后,看来这是适配器动画固有的问题,而不是ListAdapter或我自己的diff方法。
编辑:应注意的是,由于我的应用程序的工作方式,收件箱中的项目需要移至新位置并进行更新。因此,调用notifyItemMoved
和notifyItemChanged
答案 0 :(得分:2)
奇怪的是,发现这是共享元素转换的问题。显然,过渡在某种程度上导致了recyclerview的动画不正确,在删除了共享元素后,所有功能均按预期运行。