片段,不设窗户崩溃的配置变化 [英] Fragment without a view crashes on configuration change

查看:115
本文介绍了片段,不设窗户崩溃的配置变化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个用户界面,我在横向模式而不是纵向模式需要一个片段来进行显示(以期)。在纵向模式下,它应该仍然可以使用,但将使用显示其结果 ListPopupWindow 代替。

我想我可以使用&LT处理这个片段/> 标记的景观布置,同时创造编程,如果它没有启动的片段(在当我们在画像的情况下)。

这工作得很好,只要你开始在景观,如果你在创建片段的画像开始编程,当你旋转的仿真器,当它试图将片段连接到你的布局你的应用程序崩溃:

  

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

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

  

返回true,如果布局包括   作为活动视图层次的一部分   通过标签。这会   永远是真实的,当片段   通过标签创建的,   的情况除外,其中一个老   片段从一个previous恢复   状态,它不会出现在   当前状态的布局。

所以,问题是如何正确地做到这一点,或者如果有什么我失踪?

更新:

好像 isInLayout()不是表现为它应该现在也是如此。如果您手动添加了一个片段来一个容器返回FALSE。

另外,如果你添加一个片段手动到一个容器中,然后转动(设备),以不包含该布局将崩溃的布局:

  

引起的:   java.lang.IllegalArgumentException异常:无   查看发现的ID 0x7f060011的   片段SearchFragment {4042f868#2   ID = 0x7f060011 SearchFragment}在   android.app.FragmentManagerImpl.moveToState(FragmentManager.java:722)

解决方案

你有没有想出一个答案?我有一个类似的问题,并设法拿出一个解决方案。您可以轻松地做你正在尝试什么如下:

创建两个不同的布局之一的布局目录,一个在布局陆目录。一个在布局,用地目录将在横向模式下使用。作为一个占位符,您希望您的片段去,将S的FrameLayout元素,ID,再说id为my_fragment。在布局目录中的布局不应该包含与该ID的任何元素。

在您的onCreate方法,使用findViewById(R.id.my_fragment)来定位片段占位符。如果它存在,你是在横向模式下,应该添加您的片段(如果它不存在):添加(R.id.my_fragment,新MyFragment,myFragment)如果你得到空,你是在肖像模式和应不会造成碎片。

要非常小心,你从来没有更换使用标签创建的片段,与你在你的程序中动态创建一个。片段为其isInLayout返回true,是一个完全不同的野兽,那一个是它返回false。他们的生命周期是完全不同的。与其他替代一个会导致​​可怕的IllegalStateException异常片段没有创建视图的问题。

-blake

I have an UI where I need a Fragment to be displayed (with a view) in landscape mode but not in portrait mode. In portrait mode it should still be available but will display its result using ListPopupWindow instead.

I figured I could handle this by using the <fragment /> tag for the landscape layout while creating the fragment programmatically if it wasn't started (in the case when we are in portrait).

This works fine as long as you start out in landscape, if you start in portrait where the fragment is created programmatically your application will crash when you rotate the emulator when it tries to attach the fragment to your layout:

java.lang.IllegalStateException: Fragment did not create a view. at android.app.Activity.onCreateView(Activity.java:4095)

The docs for Fragment.isInLayout() seems to hint that it should be able to handle it this way:

Return true if the layout is included as part of an activity view hierarchy via the tag. This will always be true when fragments are created through the tag, except in the case where an old fragment is restored from a previous state and it does not appear in the layout of the current state.

So the question is how to do this correctly or if there is something I'm missing?

UPDATE:

Seems like isInLayout() isn't behaving as it should currently as well. It returns false if you have added a Fragment to a container manually.

Also, if you add a Fragment manually to a container and then rotate (the device) to a layout that does not contain that layout it will crash:

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

解决方案

Have you come up with an answer to this? I was having a similar problem, and managed to come up with a solution. You can easily do what you are attempting as follows:

Create two different layouts one in the layout directory, one in the layout-land directory. The one in the layout-land directory will be used in landscape mode. As a placeholder, where you want your fragment to go, use s FrameLayout element, and id it, say with the id "my_fragment". The layout in the layout directory should not contains any element with that id.

In your onCreate method, use findViewById(R.id.my_fragment) to locate the fragment placeholder. If it exists, you are in landscape mode and should add your fragment (if it does not exist already): add(R.id.my_fragment, new MyFragment, "myFragment). If you get null, you are in portrait mode and should not create the fragment.

Be very careful that you never replace a fragment created using a tag, with one that you create dynamically in your program. A fragment for which isInLayout returns true is a completely different beast, that one for which it returns false. Their lifecycles are entirely different. Replacing one with the other will lead to the dreaded IllegalStateException "Fragment did not create a view" problem.

-blake

这篇关于片段,不设窗户崩溃的配置变化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆