3

Having a flow to add fragment and later replace() fragment. All fragment are dynamically added, but not all call addToBackStack().

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

and in somewhere it could add another, like:

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

the replace() with the frgmtB will remove the frgmtA from the container R.id.frgment_holder. if press back button at this state, it will pop the frgmtB. But will it recreate the frgmtA even if it did not call addToBackStack() when did the adding?

if in the flow of adding fragment into same container with a serials mixed add() and replace() calls, and someone call addToBackStack() but someone do not, how would the back button behavior?

EDIT: after

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

will the

getSupportFragmentManager().findFragmentByTag(frgmtA.NAME);

still find the the frgmtA? what if when add frgmtA also called addToBackStack();

The doc says "This first searches through fragments that are currently added to the manager's activity; if no such fragment is found, then all fragments currently on the back stack are searched."

The case would be

  1. adding frgmtA; not call add to stack; UI state changed here;

(what if the frgmtA is not dynamically added by add(), but sepcified in layout file with class="frgmtA"?).

  1. replace() with frgmtB; addToStack();

  2. replace() with frgmtC; addToStack();

then if the stackTop is frgmtC, would like the back button press to bring back the first frgmtA with its last UI state.

Mike
  • 4,550
  • 4
  • 33
  • 47
lannyf
  • 9,865
  • 12
  • 70
  • 152

3 Answers3

6

1.

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

the replace will remove the frgmtA from the the holder and its onDestroyView will be called (but since it is referenced in the backstack’s transaction data, frgmtA is NOT destroyed). And the frgmtB will be added to the holder. Since the frgmtA is not destroyed, the

getSupportFragmentManager().findFragmentByTag(frgmtA.NAME); 

will find it.

after then, press on back button, it will pop the top transaction from the backStack, then reversing the transaction. i.e. remove frgmtB from the holder and add frgmtA back to the holder. Since there is no more reference to frgmtB its onDestroy is called.

2. in the case of

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

If want to back press to jump to frgmtA, need to override onBackPressed(), in it do

popBackStack(frgmtB.NAME, POP_BACK_STACK_INCLUSIVE), 

which will toss out the transaction in the stack above stack entry named frgmtB.NAME and do reverse the transaction on it, which will add back the frgmtA in the holder.

lannyf
  • 9,865
  • 12
  • 70
  • 152
2

try this anyone line as your demand

its 4 differnt lines code you have checked

getActivity().getSupportFragmentManager().popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);

getActivity().getSupportFragmentManager().popBackStackImmediate(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);

    FragmentTransaction transaction = getActivity().getSupportFragmentManager().beginTransaction();
    transaction.replace(R.id.framelayout, fragment);
    transaction.addToBackStack(null);

    getActivity().getSupportFragmentManager().popBackStack();
MohammedAli
  • 2,361
  • 2
  • 19
  • 36
1

Unless you interfere with the Back button logic using onBackPressed() or addOnBackStackChangedListener(), things are straight forward

  • if you add a fragment through addToBackStack(), it will be removed when Back is tapped
  • if there are no other fragments left in the back stack, app will be closed
Dimitar Genov
  • 2,056
  • 13
  • 11
  • Thanks Dimitar! But still not clear what the replace() removing the previous fragments from the container means. If the previous fragment also called addToBackStack(), does the replace()'s 'removing' destroys the previous fragments, or caches them somewhere? – lannyf Nov 03 '15 at 22:13
  • `replace()` will remove any existing fragments in the container with provided id. There is no caching. If you want to combine `replace()` with `addToBackStack()` then things become heavy. You would need to keep a reference of the positive integer returned when calling [commit()](http://developer.android.com/reference/android/app/FragmentTransaction.html#commit()). This would be your back stack id. I would recommend to stay away from complex scenarios since it's easy to lose your mind :) Either `add()`/`remove()` picked fragments rather bombing them with `replace()` or change fragment uses. – Dimitar Genov Nov 04 '15 at 04:45
  • Agree that using simple add/remove let os to handle the pushing/popping. But if need also to cover the user managed flow, the 'simple' push/pop does not help (that's where the confusion coming from). Like the case stated in the problem, has three fragments, fA, fB, fC,. fA added with add() or defined as class in xml's holder; fB and fC were added later (could be done with either add() or replace()) with addToBackStack. If it on fC there is button click to go back to fA, seems there is no way (since fA is in the holder) unless pop all and create a new fA to add from beginning. – lannyf Nov 04 '15 at 13:25