Привет, ребята!

Если вы работаете с представлениями ресайклера на Android, вы можете столкнуться с этой ужасной ошибкой: IndexOutOfBoundsException — обнаружена несогласованность. Invalid Item ## Item Position и т. д. Давайте рассмотрим несколько способов исправить это.

Понять, почему это происходит

Когда пользователь прокручивает ваше представление повторного использования во время изменения данных в списке (возможно, из-за того, что вы добавляете/удаляете элементы в фоновом режиме из-за извлечения для обновления или из-за разбивки на страницы или какого-либо процесса фоновой синхронизации), ViewHolder теряет ссылку на элемент в представлении переработчика и элемент в списке данных.

Решения

  1. Убедитесь, что вы закончили обновление данных в списке, и только затем в основном потоке уведомите адаптер представления ресайклера с помощью notifyDataSetChanged() .

2. Если вы изменяете список с помощью .add() , addAll() , remove() , removeAll() , сделайте процесс синхронизированным, прежде чем уведомлять адаптер представления ресайклера. (Или) Создайте временный список для хранения ваших новых данных и установите его непосредственно в основной список, прикрепленный к вашему адаптеру.

Например, если вы изменяете свой список следующим образом:

val dataList : MutableList<Person> = listOf() // --> used by your recyclerview for showing the list
..
..
val personData = getPersons()
..
..
dataList.addAll(personData())
dataList.add(Person(name="Parithi"))
..
..
recyclerView.adapter?.notifyDataSetChanged()

Измените код на этот:

val dataList : MutableList<Person> = listOf() // --> used by your recyclerview for showing the list
..
..
// create a temporary list
val temporaryList : MutableList<Person> = listOf() 
val personData = getPersons()
..
..
temporaryList.addAll(personData())
temporaryList.add(Person(name="Parithi"))
..
..
dataList = temporaryList // set it to the main list
recyclerView.adapter?.notifyDataSetChanged()

Решения, которые могут работать, но не рекомендуются — повлияют на работу с пользовательским интерфейсом

  1. Очистите кеш recyclerview, используяrecyclerView.getRecycledViewPool().clear();
  2. Отключите прокрутку в представлении ресайклера, когда данные обновляются, переопределив метод onTouch.

Надеюсь, эта статья помогла вам решить проблему. Спасибо за чтение и счастливого кодирования :)