在不同的容器中显示片段,具体取决于方向



我的活动有 2 种不同的 xml 布局,用于纵向和横向。当方向改变时,我正在尝试使用相同的片段,并在活动的onCreate()中使用该代码:

if (savedInstanceState == null) {
    frag = Fragment
        .instantiate(this, PlayerControlsFragment.class.getName());
} else {
    frag = fragmentManager.findFragmentByTag(FRAG_TAG);
}

然后,根据方向:

private void initLandscapePlayerFragment(FragmentTransaction ft) {
    ft.add(R.id.layout_center_top, frag);
}
private void initPortraitPlayerFragment(FragmentTransaction ft) {
    ft.add(R.id.layout_left_top, frag);
}

它给了我一个很好的

非法状态异常:无法更改片段碎片的容器 ID

事实上,当我在两个 xml 中使用相同的容器 id 时,它可以工作,但就我而言,这不是解决方案。我尝试了不同的随机解决方案(在破坏活动之前分离等)但没有成功。
知道吗?

对于其他阅读的人。请理解我们试图做什么。我们不只是在处理屏幕旋转。我们尝试在屏幕旋转和布局更改后重新附加片段。

Android 会抛出一个错误,提示未将片段附加回具有相同 ID 的容器。问题是,随着布局的改变,容器不存在,我们特别想附加到一个新的容器(因为它是一个不同的布局,即具有多个面板的风景)。

我可能和你一样沮丧。我发现你的答案没有解决方案,据我所知,这是不可能的。根本不可能在 UI 片段上设置保留实例(true) 并在屏幕旋转后重新附加。至少无论如何都不使用支持库(本机支持可能有效,我不知道/无关紧要)。

最后,我只是允许转储片段并从头开始重新创建。

这可能会很麻烦,因为后堆栈仍然存在。

我不得不打电话

super.onCreate(null)

转储片段事务后退堆栈。

然后使用我自己在 onSaveStateInsance 捆绑包中的信息根据用户对布局更改的期望重新创建屏幕(两个片段中的哪一个现在将占据整个屏幕)。

该行为是高度特定于应用的...所以我很乐意详细说明或讨论它如何适用于你,但本质上要重申,我不得不抛弃所有内容并从头开始按照用户的期望重新审视,没有任何东西自动来自 android。事实上,android 阻碍了一个只会崩溃的后堆栈,并且无法杀死后堆栈,而是将 null 传递给 super.oncreate 调用。

我也必须解决这个问题。就我而言,我第一次将片段添加到容器并"取消附加"以删除片段时使用"添加"方法。理论上,"deattach"的优点是,当你使用后面的"attach"时,片段会自动进入前一个容器。

在用户旋转设备并更改容器之前,此方法效果很好,在这种情况下,如果屏幕上不存在容器,则会出现黑屏。

有可能在

调用附加方法之前更改容器会很棒,但显然这是不可能的......在其他线程中,我有一些想法,例如在使用新容器将它们添加到屏幕之前复制片段

Android Fragment - 从一个视图移动到另一个视图?

还有其他想法吗?

通过阅读有关支持多个屏幕(#Using 配置限定符)的设计文档,您不应该根据设备方向控制使用哪种布局来膨胀视图。正确的方法是将视图的横向版本添加到 \*-land 资源文件夹中。通过将选择哪个资源的控制权移交给 Android 并删除您拥有的私有 init 方法来简化您的代码。你还有同样的问题吗?

最新更新