根据方向显示不同容器中的片段

时间:2012-05-28 15:09:37

标签: android fragment illegalstateexception

我的活动有2种不同的xml布局,适用于纵向和横向。我正试图在方向改变时使用相同的片段,在Activity的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);
}

它给了我一个很好的

  

IllegalStateException:无法更改片段Frag的容器ID

事实上,当我在两个xml中使用相同的容器ID时,它可以工作,但在我的情况下它不是一个解决方案。 我尝试了不同的随机解决方案(在破坏活动之前分离等)但没有成功。
有什么想法吗?

3 个答案:

答案 0 :(得分:0)

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

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

我可能和你一样沮丧。我发现你的答案没有解决办法,我不知道怎么回事。根本不可能在UI片段上设置setRetainInstance(true)并在屏幕旋转后重新附加。至少不使用支持库(本机支持可能有效,我不知道/不相关)。

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

这可能很麻烦,因为后座仍在那里......

我不得不打电话

super.onCreate(null)

转储片段事务backstack。

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

这种行为是高度针对特定应用的...所以我很乐意精心制作或讨论它是如何适用于你的,但基本上要重申一下,我不得不抛弃一切并从头开始按照用户的期望进行重新调整,没有任何自动来自机器人。事实上,android阻挡了一个只会崩溃并且无法杀死backstack而是将null传递给super.oncreate调用的后端堆栈。

答案 1 :(得分:0)

我也必须解决这个问题。在我的情况下,我第一次使用“添加”方法将片段添加到容器中,并使用“deattach”删除片段。从理论上讲,“deattach”的优点是,当您稍后使用“attach”时,片段会自动转到前一个容器。

这种方法可以正常工作,直到用户旋转设备并更换容器,在这种情况下,如果屏幕上没有容器,则会出现黑屏。

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

Android Fragment - move from one View to another?

还有其他想法吗?

答案 2 :(得分:-2)

通过阅读supporting multiple screens (#Using configuration qualifiers) 上的设计文档,您不应该根据设备方向控制使用哪种布局来扩大视图。正确的方法是将视图的横向版本添加到\ * - land资源文件夹。通过将选择了哪个资源的控制权移交给Android并删除您拥有的私有init方法来简化您的代码。你还有同样的问题吗?