Привет, ребята!
Если вы работаете с представлениями ресайклера на Android, вы можете столкнуться с этой ужасной ошибкой: IndexOutOfBoundsException — обнаружена несогласованность. Invalid Item ## Item Position и т. д. Давайте рассмотрим несколько способов исправить это.
Понять, почему это происходит
Когда пользователь прокручивает ваше представление повторного использования во время изменения данных в списке (возможно, из-за того, что вы добавляете/удаляете элементы в фоновом режиме из-за извлечения для обновления или из-за разбивки на страницы или какого-либо процесса фоновой синхронизации), ViewHolder теряет ссылку на элемент в представлении переработчика и элемент в списке данных.
Решения
- Убедитесь, что вы закончили обновление данных в списке, и только затем в основном потоке уведомите адаптер представления ресайклера с помощью
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()
Решения, которые могут работать, но не рекомендуются — повлияют на работу с пользовательским интерфейсом
- Очистите кеш recyclerview, используя
recyclerView.getRecycledViewPool().clear();
- Отключите прокрутку в представлении ресайклера, когда данные обновляются, переопределив метод onTouch.
Надеюсь, эта статья помогла вам решить проблему. Спасибо за чтение и счастливого кодирования :)