Не найдено представление для идентификатора при извлечении обратного стека без добавления к заднему стеку

Я работаю над приложением для Android и столкнулся с ошибкой, связанной с Fragments и FragmentTransactions. Я создал пример приложения, чтобы продемонстрировать проблему. Вот что я делаю:

  1. add Fragment1 до fragmentSpace, без добавления в стопку.
  2. replace fragmentSpace с Fragment2, добавляя в стопку как "beginning".
  3. add Fragment3 в fragmentSpace2 (который находится внутри Fragment2), без добавления в стопку.
  4. replace fragmentSpace2 с Fragment4, добавляя в стопку как null.
  5. Вызовите getFragmentManager().popBackStack("beginning", FragmentManager.POP_BACK_STACK_INCLUSIVE);, чтобы попытаться отменить все транзакции, что должно привести к тому, что пользователь снова увидит только Fragment1.

Однако приложение вылетает на шаге 5 с этой ошибкой:

java.lang.IllegalArgumentException: No view found for id 0x7f090004 (me.MitchT.testfragmenttransactions:id/fragmentSpace2) for fragment Fragment3{7f35cb6 #2 id=0x7f090004}
            at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:886)
            at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1067)
            at android.app.BackStackRecord.popFromBackStack(BackStackRecord.java:1645)
...

Я обнаружил, что если я добавлю шаг 3 в backstack, шаг 5 больше не приведет к сбою приложения, и больше не будет ошибки. Почему?

Проблема, с которой я столкнулся при добавлении шага 3 в backstack, заключается в том, что я хочу, чтобы пользователь мог нажать кнопку «Назад» после добавления Fragment3 и вернуться к Fragment1. Если я добавлю его в стопку, то когда пользователь нажмет кнопку "Назад", он удалит Fragment3, но Fragment2 все еще будет виден, поэтому он должен нажать кнопку "Назад" еще раз. Я пытаюсь избежать этого поведения с двойной кнопкой возврата.

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

Итак, я предполагаю, что мои вопросы:

  1. Почему я получаю эту ошибку?
  2. Почему я не получаю сообщение об ошибке после добавления шага 3 в стопку?
  3. Есть ли лучший способ «вернуться к началу» или вернуться к двум фрагментам за раз?

Спасибо!


person Mitch Talmadge    schedule 18.08.2015    source источник
comment
Представление с началом id не найдено. Просто используйте popbackstack().   -  person Raghunandan    schedule 18.08.2015


Ответы (1)


Насколько я понимаю. У вас есть макет фрагмента, который является контейнером в действии.

Хозяева активности Fragment1. Затем вы заменяете фрагмент 1 фрагментом 2 (добавляется в задний стек.

На этом этапе, нажав кнопку «Назад», у вас появится фрагмент 2, и вы увидите активность, в которой размещается фрагмент 1.

Fragment2 имеет макет кадра, который содержит фрагмент3. Затем у вас есть фрагмент 4, заменяющий фрагмент 3, который добавляется в задний стек.

Теперь, нажав кнопку, у вас есть getFragmentManager().popBackStack("beginning", FragmentManager.POP_BACK_STACK_INCLUSIVE);. Но нет представления с этим идентификатором.

Просто используйте popBackStack(). Фрагмент4 --> Фрагмент2 (содержит фрагмент3) --> Фрагмент1 (содержит действие).

Если вы хотите, чтобы Fragment4 размещал в Activity Fragment1, не добавляйте Fragment4 в задний стек.

Примечание. Если вам нужны вложенные фрагменты, вам нужно использовать getChildFragmentManager(). https://developer.android.com/about/versions/android-4.2.html

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

person Raghunandan    schedule 18.08.2015
comment
На шаге 2 я добавляю в backstack как начало: /MitchTalmadge/ Разве это не должно быть найдено из этого? - person Mitch Talmadge; 18.08.2015
comment
@MitchTalmadge, но у вас в стеке есть фрагмент 4. - person Raghunandan; 18.08.2015
comment
@MitchTalmadge также отмечает, что фрагмент 2 находится в заднем стеке, а фрагмент 3 и 4 размещен во фрагменте 2. - person Raghunandan; 18.08.2015
comment
Спасибо, я сделал цикл for с помощью popBackStack, и это решило проблему. Однако я до сих пор не понимаю, как backstack не может найти начало. Особенно после прочтения ответа на этот вопрос: stackoverflow.com/questions/5802141/ Насколько я понимаю, popBackStack(String, int) будет выполнять функцию popBackStack() до тех пор, пока не достигнет транзакции с указанным тегом. - person Mitch Talmadge; 18.08.2015
comment
@MitchTalmadge попробуйте то же самое, когда у вас есть фрагмент2, заменяющий фрагмент1, но это не так. также обратите внимание на его вложенные фрагменты. все еще читаю ссылку, которую вы публикуете - person Raghunandan; 18.08.2015
comment
@MitchTalmadge Я попытался добавить замену фрагмента 2 на фрагмент 4. Тогда решение по указанной вами ссылке работает так же, как и решение popBackStack с именем. Я бы также рассмотрел случай вложенных фрагментов. - person Raghunandan; 18.08.2015
comment
@MitchTalmadge, если вам нужны вложенные фрагменты, вы должны использовать getChildFragmentManager(). Просто попробуйте сохранить тот же код, который у вас был до developer.android .com/intl/ko/about/versions/android-4.2.html - person Raghunandan; 18.08.2015
comment
Черт, да! Это исправило это! Большое спасибо!! Я понятия не имел о getChildFragmentManager(), это имеет для меня гораздо больше смысла. Спасибо! - person Mitch Talmadge; 18.08.2015