如何将ViewPager设置为在侧面有两个片段的中间页面充满视图和另一个片段?

时间:2019-03-29 16:46:31

标签: android android-fragments android-viewpager

在下面的图片中,您可以看到所需的布局:

enter image description here

因此,ViewPager具有三个页面,左右页面静态地填充有两个片段(片段1和片段2),并且位于中心的页面的布局应具有顶部的工具栏,底部的工具栏和底部的工具栏。两者之间可以动态更改。

据我所知,有两种方法可以做到这一点。

  1. 在同时具有两个工具栏和动态设置Fragment0的中心页面上做一些魔术

  2. 每个应转到中心页面的片段都应具有这些工具栏,并具有处理它们中事件的相同方式,即AbstractCenterFragment上的子类,其中包含实现此布局和行为所需的所有内容。

即使实施解决方案2会更容易,出于很多原因,我也不喜欢它。我不会在这里处理,但是如果您坚持,我可以提供。

对于解决方案1,您可以建议从活动级别解决此问题,因为活动及其所有组件(视图模型等)都应处理此布局?

如果我将FragmentPagerAdapter用于ViewPager,并在包含工具栏,底部工具栏和Fragment0的中心页面中创建父片段,这将如何影响性能?

您是否还有其他建议使用其他类型的PagerAdapter来处理给定布局的行为?

谢谢!

如果对此问题的评分为-1,请保持礼貌,以解释您为什么给出它。

1 个答案:

答案 0 :(得分:0)

好的,我在给定布局的 PRIMARY_ID 12345 23456 2 rows selected. FragmentViewPagerAdapter的常规实现之间做出了混合解决方案。

这里是:

ViewPagerAdapter

在Activity中实现此适配器时,我创建了以下类:


abstract class NoMiddleFragmentPagerAdapter(private val mFragmentManager: FragmentManager) : PagerAdapter() {
    private var mCurTransaction: FragmentTransaction? = null
    private var mCurrentPrimaryItem: Fragment? = null

    abstract fun getLeftItem(): Fragment

    abstract fun getRightItem(): Fragment

    @Throws(IllegalStateException::class)
    override fun startUpdate(container: ViewGroup) {
        if (container.id == View.NO_ID) {
            throw IllegalStateException( "ViewPager with adapter $this requires a view id.")
        }
    }

    override fun instantiateItem(container: ViewGroup, position: Int): Any = if (position == MIDDLE) instantiateCentralArea(container, position) else instantiateFragment(container, position)

    private fun instantiateFragment(container: ViewGroup, position: Int) : Fragment {
        if (mCurTransaction == null) {
            mCurTransaction = mFragmentManager.beginTransaction()
        }

        val itemId = getItemId(position)

        // Do we already have this fragment?
        val name = makeFragmentName(container.id, itemId)
        var fragment = mFragmentManager.findFragmentByTag(name)
        if (fragment != null) {
            mCurTransaction!!.attach(fragment)
        } else {
            fragment = if (position == LEFT) getLeftItem() else getRightItem()
            mCurTransaction!!.add(
                container.id, fragment,
                makeFragmentName(container.id, itemId)
            )
        }
        if (fragment !== mCurrentPrimaryItem) {
            fragment.setMenuVisibility(false)
            fragment.userVisibleHint = false
        }

        return fragment
    }

    abstract fun instantiateCentralArea(container: ViewGroup, position: Int): Any

    override fun getCount(): Int = 3

    override fun destroyItem(container: ViewGroup, position: Int, `object`: Any) = if (position == MIDDLE) destroyMiddlePart(container, `object`) else destroyFragment(container, position, `object`)

    private fun destroyFragment(container: ViewGroup, position: Int, any: Any) {
        if (mCurTransaction == null) {
            mCurTransaction = mFragmentManager.beginTransaction()
        }
        mCurTransaction!!.detach(any as Fragment)
    }

    private fun destroyMiddlePart(container: ViewGroup, `object`: Any) = container.removeView(`object` as View)

    override fun setPrimaryItem(container: ViewGroup, position: Int, o: Any) {
        if (o !is Fragment) {
            super.setPrimaryItem(container, position, o)
            return
        }
        if (o !== mCurrentPrimaryItem) {
            if (mCurrentPrimaryItem != null) {
                mCurrentPrimaryItem!!.setMenuVisibility(false)
                mCurrentPrimaryItem!!.userVisibleHint = false
            }
            o.setMenuVisibility(true)
            o.userVisibleHint = true
            mCurrentPrimaryItem = o
        }
    }

    override fun finishUpdate(container: ViewGroup) {
        if (mCurTransaction != null) {
            mCurTransaction!!.commitNowAllowingStateLoss()
            mCurTransaction = null
        }
    }

    override fun isViewFromObject(view: View, any: Any): Boolean {
        return when (any) {
            is Fragment -> any.view == view
            is View -> view === any
            else -> false
        }
    }

    override fun saveState(): Parcelable? {
        return null
    }

    override fun restoreState(state: Parcelable?, loader: ClassLoader?) {}

    fun getItemId(position: Int): Long {
        return position.toLong()
    }

    companion object {
        private const val LEFT = 0
        private const val MIDDLE = 1
        private const val RIGHT = 2

        private fun makeFragmentName(viewId: Int, id: Long): String {
            return "android:switcher:$viewId:$id"
        }
    }
}