Android - 如何让recyclerview ListAdapter停止闪烁?
Android - How to make the recyclerview ListAdpater stop blinking?
我有一个回收器视图,其适配器使用 ListAdapter(版本 1.1.0):
class InnerEpisodeFragmentAdapter(
private val actCtx: Context,
) : ListAdapter<Episode, InnerEpisodeFragmentAdapter.MViewHolder>(COMPARATOR) {
...
回收器视图由来自 Room 数据库 Episode table 的 kotlin 流提供:
vm.episodesFlow().asLiveData().observe(viewLifecycleOwner) { episodes ->
episodes.let { adapter.submitList(it) }
}
@Query("SELECT * FROM Episode ORDER BY pubDate DESC")
fun episodesFlow(): Flow<List<Episode>>
作为例外,每次剧集 table 中的元组发生变化时,都会发出新的剧集列表并更新回收器视图。
它工作正常,但每次更新时都会出现可怕的闪烁。它给用户带来了糟糕的体验。
当流发出新值时如何避免闪烁?
在我的应用程序的前一个版本中,我使用了像 notifyDataSetChanged() 或 notifyItemChanged() 这样的函数,这些函数 blink.I 从来不知道我仍然可以尝试使用这些函数,但如果我不能,我会非常失望如上所示,在使用 kotlin 流程时避免闪烁。谢谢
======== 要求提供更多信息 ======
我的比较器很好,完全符合我的要求。
例如,我希望 isPlayed 在每个 recycler view item 中实时更新。它是。但是整个列表眨眼。回收站视图会消失几分之一秒,然后重新出现并显示更新后的信息。
companion object {
private val COMPARATOR = object : DiffUtil.ItemCallback<Episode>() {
override fun areItemsTheSame(oldItem: Episode, newItem: Episode): Boolean {
return oldItem === newItem
}
override fun areContentsTheSame(oldItem: Episode, newItem: Episode): Boolean {
return (oldItem.id == newItem.id)
&& (oldItem.isOnDisk == newItem.isOnDisk)
&& (oldItem.downloadId == newItem.downloadId)
&& (oldItem.isPlayed == newItem.isPlayed)
&& (oldItem.isDeleted == newItem.isDeleted)
}
}
}
你们比较者
areItemsThesame() 实施错误。您正在比较的是参考,旧对象和新对象可能不是相同的对象。相反,您有些人使用某种 uuid 来比较两者,例如主键。如果对象不同,它将 return false,因此永远不会调用 areContentsTheSame,否则如果对象相同,则没有必要比较内容,因为 oldObject 和 newObject 都指向相同的引用。
抱歉,我是从移动设备上写的,出现错误
我有一个回收器视图,其适配器使用 ListAdapter(版本 1.1.0):
class InnerEpisodeFragmentAdapter(
private val actCtx: Context,
) : ListAdapter<Episode, InnerEpisodeFragmentAdapter.MViewHolder>(COMPARATOR) {
...
回收器视图由来自 Room 数据库 Episode table 的 kotlin 流提供:
vm.episodesFlow().asLiveData().observe(viewLifecycleOwner) { episodes ->
episodes.let { adapter.submitList(it) }
}
@Query("SELECT * FROM Episode ORDER BY pubDate DESC")
fun episodesFlow(): Flow<List<Episode>>
作为例外,每次剧集 table 中的元组发生变化时,都会发出新的剧集列表并更新回收器视图。
它工作正常,但每次更新时都会出现可怕的闪烁。它给用户带来了糟糕的体验。
当流发出新值时如何避免闪烁?
在我的应用程序的前一个版本中,我使用了像 notifyDataSetChanged() 或 notifyItemChanged() 这样的函数,这些函数 blink.I 从来不知道我仍然可以尝试使用这些函数,但如果我不能,我会非常失望如上所示,在使用 kotlin 流程时避免闪烁。谢谢
======== 要求提供更多信息 ======
我的比较器很好,完全符合我的要求。 例如,我希望 isPlayed 在每个 recycler view item 中实时更新。它是。但是整个列表眨眼。回收站视图会消失几分之一秒,然后重新出现并显示更新后的信息。
companion object {
private val COMPARATOR = object : DiffUtil.ItemCallback<Episode>() {
override fun areItemsTheSame(oldItem: Episode, newItem: Episode): Boolean {
return oldItem === newItem
}
override fun areContentsTheSame(oldItem: Episode, newItem: Episode): Boolean {
return (oldItem.id == newItem.id)
&& (oldItem.isOnDisk == newItem.isOnDisk)
&& (oldItem.downloadId == newItem.downloadId)
&& (oldItem.isPlayed == newItem.isPlayed)
&& (oldItem.isDeleted == newItem.isDeleted)
}
}
}
你们比较者
areItemsThesame() 实施错误。您正在比较的是参考,旧对象和新对象可能不是相同的对象。相反,您有些人使用某种 uuid 来比较两者,例如主键。如果对象不同,它将 return false,因此永远不会调用 areContentsTheSame,否则如果对象相同,则没有必要比较内容,因为 oldObject 和 newObject 都指向相同的引用。
抱歉,我是从移动设备上写的,出现错误