Android-根据“活动”主机的方向添加不同的片段

时间:2018-08-01 13:40:18

标签: android

我从一个星期开始就遇到了这个问题,但没有成功。 我正在尝试加载两个不同的片段:PortraitTestFrag.javaLandscapeTestFrag.java,具体取决于Activity主机方向。

这些Fragments被加载到 /layout/activity_main.xml /layout-land/activity_main.xml 中,如下所示:

     <fragment
    android:id="@+id/navigationContainerFragment"      
    android:name="class name#"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>

我想要的是当我的Activity主持人是肖像时,PortraitTestFrag被加载并显示。当我的Activity处于横向时,LandscapeTestFrag应该加载并显示。

问题是PortraitTestFrag在启动时可见,但是当设备旋转LandscapeTestFrag时从不显示,甚至Activity也被销毁并重新创建。似乎第一个加载的Fragment具有优先级。

可能是什么问题?

1 个答案:

答案 0 :(得分:0)

我不建议您至少在方向改变时替换片段,至少是因为您将丢失保存到捆绑或持久保存在ViewModel / Presenter / etc中的数据。
最好使用DI或结构来更改片段内特定于方向的逻辑的实现。
如果您确实要更改整个片段,则可以创建一个代理片段来管理交换逻辑:

abstract class BaseSwitchFragment : Fragment() {

    companion object {
        private const val KEY_ORIENTATION = "ORIENTATION"
        private const val CHILD_TAG = "CHILD_TAG"
    }

    private var prevOrientation: Int? = null

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        return inflater.inflate(R.layout.fragment_switch, container, false)
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        prevOrientation = savedInstanceState?.getInt(BaseSwitchFragment.KEY_ORIENTATION)

        if (prevOrientation != resources.configuration.orientation) {
            childFragmentManager.beginTransaction()
                    .replace(R.id.fragmentContainer, buildFragment(), CHILD_TAG)
                    .commit()
        }

        prevOrientation = resources.configuration.orientation

        super.onViewCreated(view, savedInstanceState)
    }

    override fun onSaveInstanceState(outState: Bundle) {
        outState.putInt(KEY_ORIENTATION, resources.configuration.orientation)
        super.onSaveInstanceState(outState)
    }

    private fun buildFragment(): Fragment {
        if (resources.configuration.orientation == Configuration.ORIENTATION_PORTRAIT) {
            return buildPortraitFragment()
        } else {
            return buildLandscapeFragment()
        }
    }

    protected abstract fun buildPortraitFragment(): Fragment

    protected abstract fun buildLandscapeFragment(): Fragment

}

我尚未测试此代码,但可能应该可以工作。我也相信,如果要删除子片段,可以优化此代码以防止重新生成子片段。