如果可以的话,使用更具体的变更事件总是更有效率的。在最后情况下再依赖notifyDataSetChanged。RecycleView。

57
更新Android Studio到Arctic Fox版本后,我收到了这个警告。但我不知道通知数据变化的有效方法。 在我的代码中,我从网络调用中填充适配器,然后我调用notifydatasetchange,但编译器给了我这个提示: "如果可以,请始终使用更具体的更改事件。在最后情况下依赖于notifyDataSetChanged。RecycleView"
编辑问题: 他们希望我们使用DiffUtil文档而不是notifyDataSetChanged(),因为它更快。 请查看medium上的这篇文章。
3个回答

59

这意味着,如果您需要一次性更改recyclerview中的整个项列表,则使用notifyDataSetChanged()

如果您需要更改特定项,则最好使用notifyItemChanged(position),以便不会刷新和重新绑定整个数据集,如果数据集很大,则可能影响性能。

因此,这只是一个普通建议或者说警告,没有什么可担心的。:)


所以,如果适配器连接到底层数据库或其他数据提供程序的光标上,每当触发DataSetObserver时,我们都需要面对这个警告?太好了... - A. Petrov
是的,也许吧... - Dev4Life
如果你从列表中删除了所有数据,那么使用notifyDataSetChanged()会是更新RecyclerView最快的方式吗? - Micro
@Micro 它仍然会导致整个 RecyclerView 重新绑定。对于大数据更改操作,您可以使用 ListAdapter,它与 RecyclerViewAdapter 相同,并具有额外的优势。查看此示例 - ListAdapter 示例 - Dev4Life
@Dev4Life,你是说如果整个数据集发生了变化,应该使用notifyItemRangeChanged()更高效吗?(在RecyclerViewAdapter中) - Micro
@Micro 是的,有点像。如果你想改变记录的范围,那么应该使用notifyItemRangeChanged(),如果你真的需要改变整个数据集,那就使用notifyDataSetChanged()。这没有问题。警告也是这个意思。 - Dev4Life

31

函数notifyDataSetChanged会认为数据集中所有的数据都已经改变,导致使用这些数据的所有可见视图都要重新绘制。当只有部分数据发生了改变时,这是不必要的。

你需要确定数据发生更改的位置,并通知适配器仅更新这些项目。

你可以使用以下方法通知特定位置的更改:

  1. notifyItemChanged(int)
  2. notifyItemInserted(int)
  3. notifyItemRemoved(int)
  4. notifyItemRangeChanged(int, int)
  5. notifyItemRangeInserted(int, int)
  6. notifyItemRangeRemoved(int, int)

1
如果您使用ListAdapter,它不会自动知道哪个项目已更改/添加/等等吗?使用areItemsTheSame和areContentsTheSame,否则我看不出ListAdapter的好处。 - TootsieRockNRoll
7
如果我不知道数据发生了什么改变,比如从互联网刷新列表,我该使用哪种方法? - Joseph Sang

4

这只是Android Studio提出的建议,用于更新RecyclerView中的数据。

此建议是针对特定位置的RecyclerView项使用notifyItemChanged(int)、notifyItemInserted(int)、notifyItemRemoved(int) 、notifyItemRangeChanged(int, int)、notifyItemRangeInserted(int, int)和notifyItemRangeRemoved(int, int)来通知更改Recycler view items。

notifyDataSetChanged() 应该作为最后的补救措施或最终解决方案。此函数将重新初始化和重新绑定所有视图,这可能会降低性能。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接