2015-11-03 2 views
0

Наличие потока для добавления фрагмента и последующего фрагмента replace(). Все фрагменты динамически добавляются, но не все звонят addToBackStack().FragmentTransaction :: replace() с или без addToBackStack()

getSupportFragmentManager().beginTransaction() 
    .add(R.id.frgment_holder, frgmtA, frgmtA.NAME) 
    .commit(); 

и где-то можно добавить еще один, как:

getSupportFragmentManager().beginTransaction() 
    .replace(R.id.frgment_holder, frgmtB) 
    .addToBackStack(frgmtB.NAME) 
    .commit(); 

в replace() с frgmtB удалит frgmtA из контейнера R.id.frgment_holder. Если нажать кнопку возврата в этом состоянии, то появится сообщение frgmtB. Но будет ли он воссоздавать frgmtA, даже если он не вызывал addToBackStack(), когда добавляли?

Если в потоке добавления фрагмента в один и тот же контейнер с последовательными смешанными вызовами add() и replace(), а кто-то вызывает addToBackStack(), но кто-то не знает, как бы работала кнопка «назад»?

EDIT: после

getSupportFragmentManager().beginTransaction() 
     .replace(R.id.frgment_holder, frgmtB) 
     .addToBackStack(frgmtB.NAME) 
     .commit(); 

будет ли

getSupportFragmentManager().findFragmentByTag(frgmtA.NAME); 

до сих пор находят в frgmtA? что если при добавлении frgmtA также называется addToBackStack();

В документе говорится: «Сначала выполняется поиск фрагментов, которые в настоящее время добавляются к активности менеджера, если такой фрагмент не найден, все поисковые фрагменты, находящиеся в текущем стеке, будут найдены».

Случай будет

  1. добавления frgmtA; не вызывать добавление в стек; Здесь изменилось состояние пользовательского интерфейса;

(что, если frgmtA не динамически добавляется добавлением(), а sepcified в файле макета с классом = "frgmtA"?).

  1. заменить() на frgmtB; addToStack();

  2. заменить() на frgmtC; addToStack();

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

ответ

2

1.

.add(R.id.frgment_holder, frgmtA, frgmtA.NAME) 
      .commit(); 
.replace(R.id.frgment_holder, frgmtB, frgmtB.NAME) 
     .addToBackStack(frgmtB.NAME) 
     .commit();` 

необходимости замены удалит frgmtA из держателя и его onDestroyView будет называться (но так как она упоминается в данных транзакций в backstack, в frgmtA НЕ уничтожен). И frgmtB будет добавлен к держателю. Поскольку frgmtA не разрушается,

getSupportFragmentManager().findFragmentByTag(frgmtA.NAME); 

найдет.

после этого, нажмите на кнопку «Назад», он вытащит верхнюю транзакцию с задней панели, а затем перевернет транзакцию. то есть удалить frgmtB из держателя и добавить frgmtA обратно в держатель. Поскольку больше нет ссылки на frgmtB, его вызывает onDestroy.

2. в случае

add frgmtA; 
replace() with frgmtB; addToStack(); 
replace() with frgmtC; addToStack(); 

Если хотите поддержать прессу, чтобы перейти к frgmtA, необходимо переопределить onBackPressed(), в нем сделать

popBackStack(frgmtB.NAME, POP_BACK_STACK_INCLUSIVE), 

который будет подбрасывать транзакция в стеке над записью стека с именем frgmtB.NAME и сделать обратную транзакцию на ней, что добавит обратно frgmtA в держатель.

0

Если вы не мешают кнопки Назад логики с помощью onBackPressed() или addOnBackStackChangedListener(), вещи прямо вперед

  • если добавить фрагмент через addToBackStack(), он будет удален, если Назад не прослушивается
  • если нет другие фрагменты, оставшиеся в задней стопке, приложение будет закрыто
+0

Спасибо Димитар! Но до сих пор неясно, что заменит() удаление предыдущих фрагментов из контейнера. Если предыдущий фрагмент также называется addToBackStack(), выполняет ли replace() 'удаление' уничтожение предыдущих фрагментов или кэширует их где-нибудь? – lannyf

+0

'replace()' удалит любые существующие фрагменты в контейнере с предоставленным id. Кэширования нет. Если вы хотите совместить 'replace()' с 'addToBackStack()', тогда все становится тяжелым. Вам нужно будет сохранить ссылку на положительное целое число, возвращаемое при вызове [commit()] (http://developer.android.com/reference/android/app/FragmentTransaction.html#commit()). Это будет ваш задний идентификатор стека. Я бы рекомендовал держаться подальше от сложных сценариев, так как легко потерять рассудок :) Либо 'add()'/'remove()' selected, а фрагменты, вместо того, чтобы бомбить их с помощью replace() 'или использовать использование фрагментов. –

+0

Согласитесь, что с помощью простого add/remove let os обрабатывать нажатие/всплытие. Но если нужно также покрыть поток, управляемый пользователями, «простой» push/pop не помогает (вот откуда возникает путаница). Как и в случае, указанном в задаче, имеется три фрагмента: fA, fB, fC. fA с добавлением add() или определяется как класс в держателе xml; fB и fC были добавлены позже (может быть сделано с помощью add() или replace()) с помощью addToBackStack. Если на fC есть кнопка, нажмите, чтобы вернуться к fA, кажется, что нет способа (поскольку fA находится в держателе), если только не всплывают все и не создаются новые fA для добавления с начала. – lannyf