2011-02-08 1 views
21

У меня есть пользовательский интерфейс, где мне нужно отобразить (с видом) Fragment в альбомном режиме, но не в портретном режиме. В портретном режиме он все равно будет доступен, но вместо этого отобразит его результат, используя вместо этого ListPopupWindow.Фрагмент без просмотра сбоев при изменении конфигурации

Я понял, что смогу справиться с этим, используя тег <fragment /> для ландшафтного макета, создавая фрагмент программно, если он не был запущен (в случае, когда мы находимся на портрете).

Это прекрасно работает до тех пор, как вы начинаете в пейзаже, если вы начинаете в портретном, где создаются фрагмент программно приложение будет сбоить при повороте эмулятора, когда он пытается присоединить фрагмент к макету:

java.lang.IllegalStateException: Фрагмент не создал вид. на android.app.Activity.onCreateView (Activity.java:4095)

Документах для Fragment.isInLayout(), кажется, намекают, что он должен быть в состоянии справиться с ней таким образом:

возвращающие если макет включен как часть иерархии видов деятельности через тег. Это всегда верно, когда фрагменты создается с помощью тега, за исключением случая, когда старый фрагмент восстанавливается из предыдущего состояния и не появляется в расположении текущего состояния.

Итак, вопрос в том, как это сделать правильно или если что-то мне не хватает?

UPDATE:

Похоже isInLayout() не ведет себя, как он должен в настоящее время, а также. Он возвращает false, если вы добавили Fragment в контейнер вручную.

Кроме того, если добавить Fragment вручную в контейнер, а затем повернуть (устройство) в макет, который не содержит, что макет будет врезаться:

Вызванный: java.lang.IllegalArgumentException : нет вид не найдено для идентификатора 0x7f060011 для фрагмента SearchFragment {4042f868 # 2 ID = 0x7f060011 SearchFragment} на android.app.FragmentManagerImpl.moveToState (FragmentManager.java:722)

+0

Я думаю, что некоторые странности происходят с фрагментами и изменениями конфигурации. Я подал сообщение об ошибке, что-то вроде этого: http://code.google.com/p/android/issues/detail?id=14796. Порядок обратных вызовов фрагмента не так документирован, когда приложение проходит через ротацию устройства. –

+0

У меня была эта проблема довольно давно. Я не знаю, применима ли она к вам, но в моем случае добавление 'if (container == null) возвращает null;' в начале метода 'onCreateView()' block предотвращает создание представления, которое предотвращает загрузку «Фрагмента», если это не требуется при изменении ориентации. –

+0

@espi, Я пробовал это, но мой фрагмент все еще падает, так как трассировка стека даже не попадает ни в один из моих кодов. У меня есть подозрение, что это имеет какое-то отношение к моей настройке setRetainInstance. Вы это установили? – nmr

ответ

22

Пришли ли вы на это ответ? У меня была аналогичная проблема, и мне удалось найти решение. Вы можете легко сделать то, что вы пытаетесь сделать следующим образом:

Создайте два разных макета один в каталоге макета, один в каталоге макета. Один в каталоге макета-земля будет использоваться в ландшафтном режиме. В качестве заполнителя, в котором вы хотите, чтобы ваш фрагмент был включен, используйте элемент s FrameLayout и укажите его, например, с идентификатором «my_fragment». Макет в каталоге макета не должен содержать ни одного элемента с этим идентификатором.

В методе onCreate используйте findViewById (R.id.my_fragment), чтобы найти место для фрагмента. Если он существует, вы находитесь в ландшафтном режиме и должны добавить свой фрагмент (если он еще не существует): add (R.id.my_fragment, new MyFragment, «myFragment»). Если вы получите нуль, вы находитесь в портретном режиме и должны не создавайте фрагмент.

Будьте очень осторожны, чтобы вы никогда не заменяли фрагмент, созданный с помощью тега, тем, который вы создаете динамически в своей программе. Фрагмент, для которого isInLayout возвращает true, - это совершенно другой зверь, тот, для которого она возвращает ложь. Их жизненный цикл совершенно различны. Замена одной с другой приведет к ужасной IllegalStateException «Фрагмент не создать вид» проблемы.

-blake

+1

Благодарим вас за провал проблемы. Я ударился головой об этой проблеме за полдня, прежде чем нашел ваше объяснение. – mach

0

Вы r проблема также может быть связана с отсутствием макета lanscape для используемого фрагмента. У вас может быть один для портрета, и поэтому ваша программа работает нормально, но когда вы вращаете свое устройство, ОС, вероятно, ищет вид в альбомной папке и не находит вид, поэтому объявляет его отсутствующим. Убедитесь, что у вас есть просмотр как в папке «layout», так и «layout-land».