Подтвердить что ты не робот

Фрагмент без просмотра сбоев при изменении конфигурации

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

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

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

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

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

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

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

UPDATE:

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

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

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

4b9b3361

Ответ 1

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

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

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

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

-blake

Ответ 2

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