Как реализовать разбиение на страницы в Leanback VerticalGridSupportFragment с использованием библиотеки подкачки? - PullRequest
10 голосов
/ 09 мая 2019

Мы пытаемся реализовать разбиение на страницы в 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"))
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...