Вложенная предварительная выборка RecyclerView не работает только при начальной прокрутке - PullRequest
0 голосов
/ 11 января 2019

Итак, моя проблема в том, что у меня вертикальное представление переработчика с рядами вложенных горизонтальных представлений переработчика. У меня включена предварительная выборка и для начального счетчика предварительной выборки установлено значение 20 (для тестирования) для вложенных обзоров реселлера, однако при первоначальной прокрутке она не выполняется предварительной выборкой из-за ожидающих обновлений на внутреннем адаптере рециркуляции при добавлении элементов в onBindViewHolder внешнего адаптера. Вот мой внешний код адаптера. Каждый «блок» представляет собой горизонтальную прокрутку

private class BlockAdapter(val blocks: List<Block>) : RecyclerView.Adapter<VH>() {
    private val viewCreatorsByType = HashMap<Int, Block>()

    override fun getItemViewType(position: Int): Int {
        val block = blocks[position]
        val blockKey = block.viewType.ordinal
        viewCreatorsByType[blockKey] = block
        return blockKey
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): VH {
        val block = viewCreatorsByType[viewType]!!
        return VH(block.createView(parent.context, parent))
    }

    override fun onBindViewHolder(holder: VH, position: Int) {
        holder.index = position
        holder.boundPresenter = blocks[position].presenter.apply {
            attachView(holder.view)
            resume()
            present()
        }
    }

    override fun onViewRecycled(holder: VH) {
        holder.boundPresenter?.run {
            pause()
            detach()
        }
        holder.boundPresenter = null
    }

    override fun getItemCount(): Int = blocks.size
}

class VH(val view: android.view.View) : RecyclerView.ViewHolder(view) {
    var boundPresenter: Presenter? = null
    var index: Int = 0
}

Когда вызывается метод onBindViewHolder, внутренний адаптер заполняется, и карты добавляются во внутренний горизонтальный адаптер представления переработчика, но он не может выполнить предварительную выборку из-за ожидающих обновлений на горизонтальном адаптере представления переработчика. Это найдено в классе GapWorker ->

        void collectPrefetchPositionsFromView(RecyclerView view, boolean nested) {
        mCount = 0;
        if (mPrefetchArray != null) {
            Arrays.fill(mPrefetchArray, -1);
        }

        final RecyclerView.LayoutManager layout = view.mLayout;
        if (view.mAdapter != null
                && layout != null
                && layout.isItemPrefetchEnabled()) {
            if (nested) {
                // nested prefetch, only if no adapter updates pending. Note: we don't query
                // view.hasPendingAdapterUpdates(), as first layout may not have occurred 
                if (!view.mAdapterHelper.hasPendingUpdates()) { //<-This is where prefetch is failing initially since the horizontal list adapter is has a pending "add" update. 
                    layout.collectInitialPrefetchPositions(view.mAdapter.getItemCount(), this);
                }
            } else {
                // momentum based prefetch, only if we trust current child/adapter state
                if (!view.hasPendingAdapterUpdates()) {
                    layout.collectAdjacentPrefetchPositions(mPrefetchDx, mPrefetchDy,
                            view.mState, this);
                }
            }

            if (mCount > layout.mPrefetchMaxCountObserved) {
                layout.mPrefetchMaxCountObserved = mCount;
                layout.mPrefetchMaxObservedInInitialPrefetch = nested;
                view.mRecycler.updateViewCacheSize();
            }
        }
    }

Как только он выложен, я могу прокрутить вверх, и предварительная выборка работает, как и ожидалось, но это не помогает с начальным рывком при прокрутке вниз. Есть ли решение этой проблемы?

1 Ответ

0 голосов
/ 24 января 2019

Я думаю, что у вас должен быть вид держателя, затем создайте свой горизонтальный RecyclerView и затем добавьте их к этому держателю один за другим, используя horizontalListHolder.addView(yourHorizontaRecyclerView), в котором horizontalListHolder может быть вертикальным LinearLayout внутри ScrollView поэтому ваш макет будет выглядеть примерно так:

<ScrollView
    android:orientation="vertical">
    <LinearLayout
        android:orientation="vertical"
        android:id="@+id/horizontalListHolder">
        <--add your horizontal recyclerViews here !->
   </LinearLayout>

</ScrollView>

надеюсь, это поможет

...