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

Dan*_*iel 49 android android-viewholder android-recyclerview

所以我有一个活动,RecyclerView我想通过按活动中的按钮更改TextView每个项目.RecyclerViewonClickListener()

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

  1. notifyDataSetChanged的.
  2. 与如int我使用条件循环低于List.size()地方notifyItemChanged将被称为几次.

在这两种情况下,我在RecyclerViewAdapter中创建布尔变量,用于onBindViewHolder知道如何更新项目.默认情况下它是假的,按下按钮后它变为真,所以onBindViewHolder以不同的方式更新项目.

我也想知道这种方法是否合适.

nap*_*ror 63

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

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

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

这取自上述页面,

如果您正在编写适配器,则尽可能使用更具体的更改事件会更有效.依靠notifyDataSetChanged()作为最后的手段.

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

notifyItemChanged(int)
notifyItemInserted(int)
notifyItemRemoved(int)
notifyItemRangeChanged(int, int)
notifyItemRangeInserted(int, int)
notifyItemRangeRemoved(int, int)
Run Code Online (Sandbox Code Playgroud)

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

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

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


Ari*_*Ari 13

notifyDataSetChanged()如果所有数据项都不再有效,我肯定会打电话.当你打电话时notifyItemChanged(mPos),它相当于一次调用notifyItemRangeChanged(mPos, 1),并且每次调用它时requestLayout()也会被调用.另一方面,当你打电话notifyDataSetChanged()notifyItemRangeChanged(0, mList.size()),只有一个电话requestLayout().

你现在的问题应该是什么,更好的是,打电话给notifyDataSetChanged()notifyItemRangeChanged(0, mList.size())?对于那个我没有答案.

  • 我的适配器具有稳定的 ID,与几乎即时的 `notifyDataSetChanged()` 相比,使用 `notifyItemRangeChanged(0, list.size())` 被证明非常慢(对于 100 个项目数据集最多 3 秒)。对于前者,适配器出于某种原因重新创建了许多视图持有者,而对于后者,它们都被回收了。 (2认同)

Zbi*_*ski 5

I've noticed that notifyItemChanged(mPos) triggers onBindVieHolder for corresponding position even it's currently not visible.

For me, calling it in a loop for all elements was more costly than notifyDatasetChanged which redrawn only visible ones.

So be careful with large datasets.