问题描述
我有一个回收器视图,其适配器使用 listadapter(1.1.0 版):
class InnerEpisodeFragmentAdapter(
private val actCtx: Context,) : listadapter<Episode,InnerEpisodeFragmentAdapter.MViewHolder>(COMParaTOR) {
...
recycler 视图由来自 Room 数据库 Episode 表的 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>>
除此之外,每次剧集表中的元组更改时,都会发出新的剧集列表并更新回收器视图。
它工作正常,但每次更新时都会出现可怕的 BLINK。它会给用户带来糟糕的体验。
当流发出新值时如何避免这种闪烁?
在我的应用程序的先前版本中,我使用了诸如 notifyDataSetChanged() 或 notifyItemChanged() 之类的函数,它们从不闪烁。我知道我仍然可以尝试使用这些函数,但如果我无法避免闪烁时我会非常失望使用 kotlin 流程,如上所示。谢谢。
解决方法
比较者
areItemsThesame() 被错误地实现。您正在比较的是旧对象和 newObject 可能不是相同对象的引用。相反,您有些人使用某种 uuid 来比较两者,例如主键。如果对象不同,它将返回 false,因此永远不会调用 areContentsTheSame,否则如果对象相同,则因为 oldObject 和 newObject 都指向相同的引用,所以它们没有比较内容的意义。
抱歉,我是从 Mobile 写的错误
,======== 要求的附加信息 ======
我的比较器很好,完全符合我的要求。 例如,我希望在每个回收者视图项中实时更新 isPlayed。确实如此。但是整个列表一闪而过。回收站视图消失了几分之一秒,然后以更新的信息重新出现。
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)
}
}
}