Что лучше? notifyDataSetChanged или notifyItemChanged в цикле?
поэтому у меня есть активность с RecyclerView
и я хочу изменить TextView
каждый элемент RecyclerView
нажав кнопку onClickListener()
в активности.
мне интересно, что лучше с точки зрения производительности:
- использовать
notifyDataSetChanged
те. - использовать цикл с условием, как 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
которые перерисовывают только видимые.
Так что будьте осторожны с большими наборами данных.