Здравствуйте!
Делал руками пагинацию вверх/вниз по стандартному шаблону - RV, ListAdapter, DiffUtli(itemsTheSame + contentTheSame) с добавлением своего ItemLoader-а в адаптер при приближении к верхнему/нижнему краю списка и последюущим запрос в репозиторий.
Данные, которые приходят в адаптер это отсортированный лист из 50 объектов, в котором при каждом обновлении изменяются максимум 20 первых или последних. На экране видно не больше 7-8 штук. Т.е. гарантируется, что при каждом обновлении списка, видимые в текущий момент времени итемы присутсвуют в новом спискt, не изменились и сохранили относительную друг друга позициию.
При скролле вниз лоадер добавлялся так:
val cachedList = currentData.toMutableList()
cachedList.add(item)
updateData(cachedList.toList())
при скролле вверх так:
val cachedList = currentData.toMutableList()
cachedList.add(0, item)
updateData(cachedList.toList())
updateData() просто:
open fun updateData(data: List<AdapterItem>) {
currentData = data
submitList(data)
}
Всё работала гладко за исключением одного момента - при быстром скролле вверх (т.е. кейсе при котором, данные не успевали обновляться бесшовно и пользователь успевал увидеть лоадер) адаптер терял текущий итем и перскакивал в начало новых данных. Методом тыка решилось это следующим образом:
val cachedList = currentData.toMutableList()
cachedList[0] = item
updateData(cachedList.toList())
Я попытался погрузиться в DiffUtil и вроде вычитал, что из-за добавления при скролле вверх itemLoader в начало промежуточного списка, все индексы в нём ехали и DiffUtils при получении обновлённых данных вызывал notifyItemRangeChanged с перерисовкой всего и вся. Но я не смого понять, почему если лоадер вообще не добавлять, не трогая старый лист до обновления, всё опять ехать начинает, хотя никакой внутренней логики связанной с наличием в списке итема лоадера в RV нет.
Сорян, если путанно, но как смог:)