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

Posted

技术标签:

【中文标题】没有视图的片段在配置更改时崩溃【英文标题】:Fragment without a view crashes on configuration change 【发布时间】:2011-06-23 15:38:10 【问题描述】:

我有一个用户界面,我需要一个Fragment 以横向模式显示(带有视图),而不是纵向模式。在纵向模式下,它应该仍然可用,但将改为使用 ListPopupWindow 显示其结果。

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

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

java.lang.IllegalStateException: 片段没有创建视图。 在 android.app.Activity.onCreateView(Activity.java:4095)

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

如果包含布局,则返回 true 作为活动视图层次结构的一部分 通过标签。这会 当片段为真时 通过标签创建, 除非是旧的 片段是从以前的 状态,它不会出现在 当前状态的布局。

所以问题是如何正确执行此操作,或者我是否缺少某些东西?

更新:

似乎isInLayout() 的行为不像现在应该的那样。如果您手动将Fragment 添加到容器中,它将返回 false。

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

原因: java.lang.IllegalArgumentException:否 为 id 0x7f060011 找到的视图 片段 SearchFragment4042f868 #2 id=0x7f060011 SearchFragment 在 android.app.FragmentManagerImpl.moveToState(FragmentManager.java:722)

【问题讨论】:

我认为片段和配置更改有些奇怪。我提交了一份关于我发现类似于以下内容的错误报告:code.google.com/p/android/issues/detail?id=14796。当应用程序经历设备轮换时,片段回调的顺序没有记录。 我很久以前就遇到过这个问题。我不知道它是否适用于您,但就我而言,在 onCreateView() 片段方法的开头添加 if (container == null) return null; 会阻止创建视图,这会阻止 Fragment 在不需要时加载关于方向变化 @espi,我试过了,但我的 Fragment 仍然崩溃,堆栈跟踪甚至从未命中我的任何代码。我有一种预感,它与我的设置 setRetainInstance 有关。你设置了吗? 不,我在保留实例方面遇到了很多问题,而且我真的不需要保留它们,所以我只是摆脱了实例。 我阅读了setRetainInstance 的文档,它说它与后堆栈不兼容。我正在使用后台堆栈,所以这是我的问题。 developer.android.com/reference/android/app/… @hackbod:如果您使用setRetainInstance 将片段添加到后台堆栈,那么如果您抛出其中一个防白痴异常,那就太好了 【参考方案1】:

你想出答案了吗?我遇到了类似的问题,并设法提出了解决方案。您可以轻松地执行您正在尝试的操作,如下所示:

创建两个不同的布局,一个在 layout 目录,一个在 layout-land 目录。 layout-land 目录中的那个将用于横向模式。作为一个占位符,你希望你的片段去哪里,使用 s FrameLayout 元素,并 id 它,说 id 为“my_fragment”。布局目录中的布局不应包含任何具有该 id 的元素。

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

请务必小心,切勿将使用标签创建的片段替换为您在程序中动态创建的片段。 isInLayout 返回 true 的片段是完全不同的野兽,它返回 false 的片段。它们的生命周期完全不同。用另一个替换一个会导致可怕的 IllegalStateException “Fragment did not create a view” 问题。

-布莱克

【讨论】:

感谢您解决问题。在找到您的解释之前,我一直在努力解决这个问题半天。【参考方案2】:

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

【讨论】:

如果布局域中没有视图,那么 Android 只会使用布局中的视图,所以这不是问题。

以上是关于没有视图的片段在配置更改时崩溃的主要内容,如果未能解决你的问题,请参考以下文章

Android Studio - 在片段之间更改时底部导航崩溃

任何更改后的 Android Firebase 数据库活动/片段正在关闭

每当我尝试从 Fragment java 文件中更改片段的某些属性时,应用程序就会崩溃

发生配置更改时如何不重置我的片段?

多次调用片段 onCreateView

后堆栈中的配置更改片段现在正在共享 FrameLayout?