I am working on fragment transaction, and the backstack is like this:
fragA => fragB => fragC => fragD
I would like to return to f
Because the "back stack" has a stack-like behaviour...last-in, first-out...the last fragment you added to the back stack will be popped out of the back stack first. You will need to implement the behaviour you required manually by specifying your own. This is not that hard using the FragmentManager
class methods.
If you "tag" your fragments as you add them to the transaction...
fragmentTransaction.add(new FragmentA(), "FragmentA_Tag");
you can later determine which fragment to show when the back button is pressed...
FragmentA f = fragmentManager.findFragmentByTag("FragmentA_Tag");
if(f != null){
f.show();
}
How you determine which fragment to show it's entirely up to you. You can keep track of the current visible fragment or you can use the isHidden method of the Fragment
class...BTW, I'm talking about native fragments here, not support library's fragment.
You an override the onbackpressed (Mainactivity) and using the getBackStackEntryCount() of the fragment manager, you can check if its not equal to 1 and popbackstack on only that condition.
@Override
public void onBackPressed() {
if (getSupportFragmentManager().getBackStackEntryCount() > 0) {
if (!(getSupportFragmentManager().getBackStackEntryCount() == 1)) {
getSupportFragmentManager().popBackStack() ;
}
}
}
Mark my words, complete FragmentTransaction
s are added to backstack not just a fragment, means even if you add and remove fragment in a single transaction calling poBackStack()
will reverse the complete transaction. Passing a tag in its argument pops all the transaction till the tagged transaction or even pops the tagged transaction (in case FragmentManager.POP_BACK_STACK_INCLUSIVE
added to the argument)
So it's more about how you added it not how you removing it.
See Performing Fragment Transactions
E.g. you can do following:
P.S. There are other ways how to do what you want. It depends...
After looking through many posts, I figured it out this way:
in fragC => fragD method, do two transactions:
1 clear back stacks, fragC => fragA
2 fragA => fragD
But in this way, the original state of fragA may be destroyed.
public static void changeFragCtoD(FragmentManager fm, Fragment fragD){
fm.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
FragmentTransaction fragmentTransaction = fm.beginTransaction();
fragmentTransaction
.replace(R.id.containerViewId, new fragAClass())
.commit();
FragmentTransaction fragmentTransaction = fm.beginTransaction();
fragmentTransaction
.replace(R.id.containerViewId, fragD)
.addToBackStack(fragD.getClass().getName())
.commit();
}
Now pressing back on fragD goes back to fragA.
I know it's too late as an answer to your question, but this might be helpful to other people. Since I have been looking for a solution for the past few days... I have solved it out with using for loop, and I think it's the simplest possible way.
First, initialize an integer in this way
int count = getSupportFragmentManager().getBackStackEntryCount();
where getBackStackEntryCount() will count the number of transactions.
And then just before calling the FragmentTransaction method in your fragD add this for loop
for (int i = 0; i < count; i++){
getSupportFragmentManager().popBackStack();
}
for loop will do the trick for you and popBackStack() will return you to the fragA
it looks like this
int count = getSupportFragmentManager().getBackStackEntryCount();
for (int i = 0; i < count; i++){
getSupportFragmentManager().popBackStack();
}
fragmentTransaction.replace(R.id.frame_layout, new FoodFragment(), "Food").addToBackStack(null);
fragmentTransaction.commit();