什么更好?循环中的notifyDataSetChanged或notifyItemChanged?

时间:2015-11-18 20:05:33

标签: android android-recyclerview android-viewholder

所以我有RecyclerView的活动,我希望通过按下活动中TextView的按钮来更改RecyclerView中每个项目的onClickListener()

我想知道在性能方面哪些更好:

  1. 使用notifyDataSetChanged个。
  2. 使用类似int的条件的循环i小于List.size(),其中notifyItemChanged将被调用几次。
  3. 在这两种情况下,我在RecyclerView适配器中创建布尔变量,onBindViewHolder使用它来了解如何更新项目。默认情况下它是假的,按下按钮后它变为真,所以onBindViewHolder以不同的方式更新项目。

    此外,我想知道这种方法是否适用。

3 个答案:

答案 0 :(得分:60)

如果您只是更新视图的一部分,请使用notifyItemRangeChanged()notifyItemChanged()代替notifiyDataSetChanged()。这里的差异与结构变化项目变更有关。这是在找到here的android开发者RecyclerView.Adapter文档上。

这是两种类型变化之间差异的另一个消息:

  

有两种不同类别的数据更改事件,即项目更改   和结构变化。项目更改是指单个项目具有的项目   数据已更新,但未发生任何位置更改。结构   更改是在数据中插入,删除或移动项目的时间   集。

这取自上述页面,

  

如果您正在编写适配器,使用它将始终更有效   如果可以,更具体的变更事件。依靠   notifyDataSetChanged()作为最后的手段。

所以,只是为了澄清使用notifyDataSetChanged()作为最后的手段,而是问问自己是否可以预先形成其中一种方法,如果你可以改为使用它:

notifyItemChanged(int)
notifyItemInserted(int)
notifyItemRemoved(int)
notifyItemRangeChanged(int, int)
notifyItemRangeInserted(int, int)
notifyItemRangeRemoved(int, int)

这是有道理的,因为notifyDataSetChanged()几乎会尝试根据数据重绘所有内容并且不做任何先前的假设,而其他方法只会查找更改。这意味着适配器必须完成更多不必要的工作。这就是notifyDataSetChanged()的作用:

  

此事件未指定数据集的更改内容,   强迫任何观察者假设所有现有的物品和结构   可能不再有效。 LayoutManagers将被迫完全重新绑定   并重新布局所有可见的视图。

使用增量或范围方法也是有意义的,因为您正在更改文本,您需要获取每个新文本,当您这样做时,您应该告诉适配器您更改了它。现在,如果您点击按钮并获取所有新文本值,并创建新列表或其他内容,则调用重notifyDataSetChanged()

答案 1 :(得分:13)

如果所有数据项都不再有效,我肯定会调用notifyDataSetChanged()。当您致电notifyItemChanged(mPos)时,它相当于对notifyItemRangeChanged(mPos, 1)的调用,每次调用requestLayout()时,也会调用notifyDataSetChanged()。另一方面,当您致电notifyItemRangeChanged(0, mList.size())requestLayout()时,只有一次致电notifyDataSetChanged()

您的问题现在应该是,更好的是,拨打notifyItemRangeChanged(0, mList.size())if x == 0.0: print "x is zero" ?对于那个我没有答案。

答案 2 :(得分:3)

我注意到notifyItemChanged(mPos)触发了onBindVieHolder相应的位置,即使它目前不可见。

对我来说,在循环中为所有元素调用它比仅重新绘制可见元素的notifyDatasetChanged更昂贵。

所以要小心大数据集。