RecyclerView 的 DiffUtil 在所有可见项都被替换时滚动列表

问题描述 投票:0回答:1

我正在使用

RecyclerView
ListAdapter
,其中显示 2 种类型的项目:内容和占位符。

在此示例中,初始列表包含 10 个内容项和 10 个占位符项,然后我将其替换为另外 10 个内容项(= 总共 20 个项)。

使用

ListAdapter.submitList(list)
执行此操作可按预期工作并显示正确的更改动画。就像这个 GIF 所示:

但是,当我滚动到屏幕上显示 only 占位符的部分时,

.submitList(list)
会导致不必要的滚动,如以下 GIF 所示:

我的比较逻辑:(应该没问题,通常所有动画都按预期工作)

sealed class MyItem {
    data class Content(val text: String) : MyItem()
    data class Placeholder(val text: String) : MyItem()
}

class MyDiffCallback : DiffUtil.ItemCallback<MyItem>() {

    override fun areItemsTheSame(oldItem: MyItem, newItem: MyItem): Boolean =
        oldItem::class == newItem::class && when (oldItem) {
            is MyItem.Content -> oldItem.text == (newItem as MyItem.Content).text
            is MyItem.Placeholder -> oldItem.text == (newItem as MyItem.Placeholder).text
    }

    override fun areContentsTheSame(oldItem: MyItem, newItem: MyItem): Boolean =
        oldItem == newItem
}

可能出了什么问题?这真的按预期工作吗?我只是错过了一些东西?

  • 我已经检查了其他 Stackoverflow 问题的一些解决方案 - 主要是关于使 RecyclerView 和项目不可聚焦,例如这里 - 他们没有解决我的问题。
  • 我也尝试使用普通的
    RecyclerView.Adapter
    并执行以下操作 通过
    DiffUtil.calculateDiff(...)
    手动比较新列表 - 这有同样的问题(
    ListAdapter
    毕竟在内部使用
    DiffUtil
  • 我设法通过对更改的确切项目执行
    adapter.notifyItemRangeChanged(...)
    来完成解决方法 - 这有效并且不会导致滚动,但我对此解决方法不满意,并且不想将其应用到我的所有功能中
android android-recyclerview android-diffutils
1个回答
0
投票

在 areContentsTheSame() 中尝试这个

return if(oldItem is MyItem.Placeholder && newItem is MyItem.Content) true 
else oldItem == newItem
© www.soinside.com 2019 - 2024. All rights reserved.