【发布时间】:2019-09-27 00:37:18
【问题描述】:
我们正在尝试使用架构组件分页库在 Leanback VerticalGridSupportFragment 中实现分页。 Leanback 本身与 Paging Library 没有任何开箱即用的兼容性,因此我们扩展了它的 ObjectAdapter 类并设法非常轻松地实现 append 和 clear 操作但是我们很难使 modify 操作正常工作。在内容修改操作期间,分页库的 PagedList 类使用 AsyncPagedListDiffer 计算差异,该类在内部使用 PagedStorageDiffHelper 这是一个包私有类,它在内部使用 PagedList 的包私有 PagedStorage 字段来访问实际的底层数据。因此,由于可见性限制,我们无法实现与分页库内部使用的相同逻辑。我们正在寻找一种干净而聪明的方法来使 Leanback 与 Paging 一起工作,而无需提取和修改两者的任何内部结构。这是我们的 ObjectAdapter 实现,它支持追加和清除数据,但不支持内容修改。
有没有人设法通过分页库在 Leanback 中实现分页?
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"))
}
}
}
【问题讨论】:
-
您好,您找到解决问题的方法了吗?我也在寻找一种在 Leanback 上实现分页的干净方法。谢谢!
-
现在有一个leanback-paging模块在alpha中,它实现了paging3的必要钩子:maven.google.com/web/…
标签: android android-tv leanback android-paging-library