我们正在尝试使用Architecture Components Paging Library在Leanback VerticalGridSupportFragment中实现分页。由于Leanback本身没有任何与Paging Library的兼容性,所以我们扩展了它的ObjectAdapter类,并成功实现了追加和清除操作。但是修改操作却令我们很难实现。在内容修改操作期间,Paging Library的PagedList类使用AsyncPagedListDiffer计算差异,它内部使用PagedStorageDiffHelper,而它是一个包私有类,它内部使用PagedList的包私有PagedStorage字段来访问实际底层数据。因此,由于可见性限制,我们无法实现与Paging Library内部相同的逻辑。我们正在寻找一种干净而巧妙的方法,使Leanback能够与Paging一起工作,而不需要提取和修改任何两者的内部。这是我们支持追加和清除数据的ObjectAdapter的实现,但不支持内容修改。请问是否有人曾经通过Paging Library实现了在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"))
}
}
}