Мы пытаемся реализовать разбиение на страницы в Leanback VerticalGridSupportFragment с библиотекой подкачки компонентов архитектуры. Сам по себе Leanback не имеет никакой совместимости с библиотекой подкачки, поэтому мы расширили его класс ObjectAdapter и сумели довольно просто реализовать операции append и clear , но мы испытывают затруднения, пытаясь заставить изменить операцию. Во время операции изменения содержимого класс PagedList библиотеки Paging вычисляет diff с использованием AsyncPagedListDiffer, который внутренне использует PagedStorageDiffHelper, который является частным пакетом, и внутренне использует приватное поле PagedStorage пакета PagedList для получения доступа к фактическим базовым данным. Таким образом, мы не можем реализовать ту же логику, которую использует библиотека подкачки из-за ограничений видимости. Мы ищем чистый и умный способ заставить Leanback работать вместе с Пейджингом, не извлекая и не изменяя внутренние компоненты любого из двух. Это наша реализация ObjectAdapter, которая поддерживает добавление и очистку данных, но не поддерживает изменение содержимого.
Кому-нибудь когда-нибудь удавалось реализовать пейджинг в Leanback через Paging Library?
class LeanbackVerticalGridPagedListAdapter<T>(
presenter: Presenter,
private val stubItem: T
) : ObjectAdapter(presenter) {
private val mUpdateCallback = object : ListUpdateCallback {
override fun onInserted(position: Int, count: Int) {
notifyItemRangeInserted(position, count)
}
override fun onRemoved(position: Int, count: Int) {
notifyItemRangeRemoved(position, count)
}
override fun onMoved(fromPosition: Int, toPosition: Int) {
notifyItemMoved(fromPosition, toPosition)
}
override fun onChanged(position: Int, count: Int, payload: Any?) {
notifyItemRangeChanged(position, count, payload)
}
}
private var mPagedList: PagedList<T>? = null
private var mSnapshot: PagedList<T>? = null
private val mPagedListCallback = object : PagedList.Callback() {
override fun onInserted(position: Int, count: Int) {
mUpdateCallback.onInserted(position, count)
}
override fun onRemoved(position: Int, count: Int) {
mUpdateCallback.onRemoved(position, count)
}
override fun onChanged(position: Int, count: Int) {
mUpdateCallback.onChanged(position, count, null)
}
}
override fun size(): Int =
mPagedList?.size
?: mSnapshot?.size
?: 0
override fun get(index: Int): T? =
mPagedList?.let {
it.loadAround(index)
it[index] ?: stubItem
} ?: mSnapshot?.let {
it[index]
} ?: throw IndexOutOfBoundsException("Item count is zero, getItem() call is invalid")
fun submitList(pagedList: PagedList<T>?) {
if (pagedList == null) {
val removedCount = size()
if (mPagedList != null) {
mPagedList!!.removeWeakCallback(mPagedListCallback)
mPagedList = null
} else if (mSnapshot != null) {
mSnapshot = null
}
// dispatch update callback after updating mPagedList/mSnapshot
mUpdateCallback.onRemoved(0, removedCount)
return
}
if (mPagedList == null && mSnapshot == null) {
// fast simple first insert
mPagedList = pagedList
pagedList.addWeakCallback(null, mPagedListCallback)
// dispatch update callback after updating mPagedList/mSnapshot
mUpdateCallback.onInserted(0, pagedList.size)
return
}
if (mPagedList != null) {
// first update scheduled on this list, so capture mPages as a snapshot, removing
// callbacks so we don't have resolve to updates against a moving target
mPagedList!!.removeWeakCallback(mPagedListCallback)
mSnapshot = mPagedList!!.snapshot() as PagedList<T>
mPagedList = null
}
if (mSnapshot == null || mPagedList != null) {
DevUtil.crashDuringDevelopment(IllegalStateException("must be in snapshot state to diff"))
}
}
}