没有视图的片段在配置更改时崩溃

我有一个 UI,我需要在横向模式下显示(带视图),但在纵向模式下不显示。在纵向模式下,它应该仍然可用,但会改为使用显示其结果。FragmentListPopupWindow

我认为我可以通过使用横向布局的标签来处理这个问题,同时以编程方式创建片段(如果它没有启动(在我们处于纵向的情况下)。<fragment />

只要您从横向开始,这就可以正常工作,如果您以纵向方式创建片段,则当您在尝试将片段附加到布局时旋转模拟器时,应用程序将崩溃:

java.lang.IllegalStateException:Fragment 没有创建视图。at android.app.Activity.onCreateView(Activity.java:4095)

的文档似乎暗示它应该能够以这种方式处理它:Fragment.isInLayout()

如果布局通过标记作为活动视图层次结构的一部分包含在内,则返回 true。当通过标记创建片段时,这将始终如此,除非旧片段是从以前的状态恢复并且它不会出现在当前状态的布局中。

所以问题是如何正确地做到这一点,或者如果我错过了什么?

更新:

似乎没有像现在这样表现。如果已手动将 a 添加到容器,则返回 false。isInLayout()Fragment

此外,如果将手动添加到容器,然后旋转(设备)到不包含该布局的布局,它将崩溃:Fragment

Caused by: java.lang.IllegalArgumentException: no view for id 0x7f060011 for fragment SearchFragment{4042f868 #2 id=0x7f060011 SearchFragment} at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:722)


答案 1

你有没有想出一个答案?我遇到了类似的问题,并设法提出了一个解决方案。您可以轻松地执行以下操作:

创建两个不同的布局,一个在布局目录中,一个在布局陆地目录中。布局-土地目录中的那个将在横向模式下使用。作为占位符,您希望片段转到何处,请使用 s FrameLayout 元素,并将其 id 化为 id“my_fragment”。布局目录中的布局不应包含具有该 ID 的任何元素。

在 onCreate 方法中,使用 findViewById(R.id.my_fragment) 查找片段占位符。如果它存在,则处于横向模式,并且应该添加您的片段(如果它尚不存在):add(R.id.my_fragment,新的MyFragment,“myFragment”)。如果获得 null,则表示您处于纵向模式,不应创建片段。

要非常小心,切勿将使用标记创建的片段替换为在程序中动态创建的片段。对于 isInLayout 返回 true 的片段,它是一个完全不同的野兽,它返回 false 的那个片段。它们的生命周期完全不同。用另一个替换一个将导致可怕的 IllegalStateException “Fragment 没有创建视图”问题。

-布莱克


答案 2

您的问题也可能是由于您正在使用的片段没有 lanscape 布局。您可能有一个纵向视图,因此您的程序运行良好,但是当您旋转设备时,操作系统可能会在横向文件夹中查找视图,并且找不到该视图,因此将其声明为丢失。检查您是否在“布局”和“布局土地”文件夹中都有视图。


推荐