Что лучше? notifyDataSetChanged или notifyItemChanged в цикле?

поэтому у меня есть активность с RecyclerView и я хочу изменить TextView каждый элемент RecyclerView нажав кнопку onClickListener() в активности.

мне интересно, что лучше с точки зрения производительности:

  1. использовать notifyDataSetChanged те.
  2. использовать цикл с условием, как int i меньше, чем List.size() здесь notifyItemChanged будет вызвано несколько раз.

в обоих случаях я создаю логическую переменную в RecyclerView адаптер, который используется onBindViewHolder чтобы знать, как обновить пункт. По умолчанию это false, и после нажатия кнопки он становится true so onBindViewHolder обновляет элемент по-разному.

также я хотел бы знать, подходит ли этот подход вообще.

3 ответов


если вы просто обновляете одну часть представления, используйте notifyItemRangeChanged()или notifyItemChanged() вместо notifiyDataSetChanged(). Разница здесь связана с структурные изменения vs пункт изменений. Это на Android разработчиков RecyclerView.Adapter документации здесь.

вот еще один лакомый кусочек о различиях между двумя типами изменений:

существует два разных класса событий изменения данных, изменения элементов и структурные изменения. Изменения элемента, когда один элемент имеет данные обновлены, но никаких позиционных изменений не произошло. Структурный изменения - это когда элементы вставляются, удаляются или перемещаются внутри данных набор.

это взято из вышеупомянутой страницы,

если вы пишете адаптер всегда будет более эффективным в использовании более конкретные события изменения, если вы можете. Полагаться notifyDataSetChanged() в качестве последнего курорт.

так что просто уточнить использование notifyDataSetChanged() как в крайнем случае, и вместо этого спросите себя, Можете ли вы вместо этого преформировать один из этих методов, и если вы можете использовать его вместо этого:

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

что имеет смысл, потому что notifyDataSetChanged() будет в значительной степени пытаться перерисовать все на основе данных и не делать никаких предыдущих предположений, в то время как другие методы будут просто искать изменения. Это означает, что адаптер должен делать намного больше работы, которая не является необходимой. Это notifyDataSetChanged() тут:

это событие не указывает, что изменилось в наборе данных, заставляет наблюдателей предположить, что все существующие элементы и структура может больше не быть действительным. LayoutManagers будут вынуждены полностью перестроиться и ретранслировать все видимые виды.

это также имеет смысл использовать инкрементный или диапазон подхода, потому что вы меняете текст, вам нужно пойти получить каждый новый текст, и когда вы это сделаете, вы должны сказать адаптер, который вы изменили. Теперь, если вы нажмете кнопку и получите все новые текстовые значения и создадите новый список или что-то еще, вызовите heavy notifyDataSetChanged().


Я бы обязательно позвонил notifyDataSetChanged() Если все элементы данных ar больше не действительны. Когда вы звоните notifyItemChanged(mPos), Это эквивалентно вызову к notifyItemRangeChanged(mPos, 1), и каждый раз она называется, requestLayout() также называется. С другой стороны, когда вы звоните notifyDataSetChanged() или notifyItemRangeChanged(0, mList.size()), есть только один вызов requestLayout().

Ваш вопрос теперь должен быть, что лучше, вызов notifyDataSetChanged() или notifyItemRangeChanged(0, mList.size())? На этот вопрос у меня нет ответа.


Я заметил, что notifyItemChanged(mPos) триггеры onBindVieHolder для соответствующей позиции даже она в настоящее время не видна.

для меня вызов его в цикле для всех элементов был дороже, чем notifyDatasetChanged которые перерисовывают только видимые.

Так что будьте осторожны с большими наборами данных.