ViewPager2:getPageWidth 替代方案

ViewPager2: getPageWidth alternative

我用 ViewPager2 替换了 ViewPager,但我有问题。 ViewPager 已修复 3 个页面。第二页比其他页大。当第1页或第3页可见时,第2页的一小部分也可见,当第2页可见时,其他页面不可见。为此,我使用了适配器方法

override fun getPageWidth(position: Int): Float {
    return if (position != MAIN_PAGE) WIDTH_SMALL_PERCENT
    else super.getPageWidth(position)
}

但是 ViewPager2 的适配器没有这个方法,我不知道怎么做。

现在没有黑客是不可能的。我创建功能请求 https://issuetracker.google.com/issues/150232913.
并且在预期功能我创建扩展方法来设置自定义布局管理器

package androidx.viewpager2.widget

import androidx.recyclerview.widget.RecyclerView
import java.lang.reflect.Field


fun ViewPager2.setLayoutManager(layoutManager: RecyclerView.LayoutManager) {
    mRecyclerView.layoutManager = layoutManager
    mRecyclerView.clearOnChildAttachStateChangeListeners() // to ability set exact view size
    setValueToField("mLayoutManager", layoutManager)
    mScrollEventAdapter.setValueToField("mLayoutManager", layoutManager) // to correct work ViewPager2.OnPageChangeCallback
}

private fun Any.setValueToField(field: String, value: Any) {
    val f1: Field = this.javaClass.getDeclaredField(field)
    f1.isAccessible = true
    f1.set(this, value)
    f1.isAccessible = false
}

并创建自定义 LayoutManager

class WidePageLayoutManager(
        private val viewPager: ViewPager2,
        private val viewSmallPercentage: Float,
        private val smallViewPosition: IntArray
) : LinearLayoutManager(viewPager.context, HORIZONTAL, false) {


    // copied from ViewPager2.LinearLayoutManagerImp
    override fun calculateExtraLayoutSpace(state: RecyclerView.State, extraLayoutSpace: IntArray) {
        val pageLimit: Int = viewPager.offscreenPageLimit
        val offscreenSpace: Int = viewPager.pageSize * pageLimit
        extraLayoutSpace[0] = offscreenSpace
        extraLayoutSpace[1] = offscreenSpace
    }

    // copied from ViewPager2.LinearLayoutManagerImp
    override fun requestChildRectangleOnScreen(
            parent: RecyclerView,
            child: View,
            rect: Rect,
            immediate: Boolean,
            focusedChildVisible: Boolean
    ): Boolean {
        return false // users should use setCurrentItem instead
    }

    // this need to show MainPage bounds on left/right side menu
    override fun checkLayoutParams(lp: RecyclerView.LayoutParams?): Boolean {
        if (lp != null && lp.viewAdapterPosition in smallViewPosition) {
            lp.width = (width * viewSmallPercentage).toInt()
        }
        return super.checkLayoutParams(lp)
    }

    override fun canScrollHorizontally(): Boolean {
        return super.canScrollHorizontally() && viewPager.isEnabled
    }
}