Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Nested Fragments and The Back Stack

Does the Back Stack support interaction with nested Fragments in Android?

If it does, what am I doing wrong? In my implementation, the back button is completely ignoring the fact that I added this transaction to the back stack. I'm hoping it is not because of an issue with nested fragments and just me doing something incorrectly.

The following code is inside of one of my fragments and is used to swap a new fragment with whatever nested fragment is currently showing:

     MyFragment fragment = new MyFragment();
     FragmentTransaction ft = getChildFragmentManager().beginTransaction();
     ft.setCustomAnimations(R.animator.slide_in_from_right, R.animator.slide_out_left, R.animator.slide_in_from_left, R.animator.slide_out_right);
     ft.addToBackStack(null);
     ft.replace(R.id.myFragmentHolder, fragment);
     ft.commit();
like image 968
MikeS Avatar asked Dec 04 '12 15:12

MikeS


People also ask

What is fragment back stack?

If you added or removed multiple fragments within a single transaction, all of those operations are undone when the back stack is popped. The optional name provided in the addToBackStack() call gives you the ability to pop back to that specific transaction using popBackStack() .

What are nested fragments?

Fragments represent a behavior or portion of UI in an Activity. Fragments are mostly used in tablets to divide screen and utilize screen space in efficient way. With Android 4.2 nested fragments are introduced, with which now you can embed fragments inside fragments.

How can I maintain fragment state when added to the back stack?

Solution: Save required information as an instance variable in calling activity. Then pass that instance variable into your fragment.

What is FragmentManager class?

FragmentManager which is used to create transactions for adding, removing or replacing fragments. fragmentManager. beginTransaction(); Start a series of edit operations on the Fragments associated with this FragmentManager. The FragmentTransaction object which will be used.


2 Answers

I have the same problem, I would like to nest fragments, and to keep a back stack for each nested fragment.

But... it seems that this case is not handled by the v4 support library. In the FragmentActivity code in the library, I can find :

public void onBackPressed() {
    if (!mFragments.popBackStackImmediate()) {
        finish();
    }
}

The mFragments represents the FragmentManager of the activity, but it does not seem this manager "propagates" the pop to children managers. A workaround would be to manually call the popBackStackImmediate() on the child manager, like this in the activity inherited from FragmentActivity :

private Fragment myFragmentContainer;

    @Override
    public void onBackPressed() {
            if (!myFragmentContainer.getChildFragmentManager().popBackStackImmediate()) {
                finish(); //or call the popBackStack on the container if necessary
            }
    }

There might be a better way, and a more automated way, but for my needs it is allright.

like image 71
la_urre Avatar answered Sep 17 '22 18:09

la_urre


In my current project we have multiple "nested layers" so I've come up with following workaround to automatically pop backstack only for top level fragment managers:

@Override
public void onBackPressed() {
    SparseArray<FragmentManager> managers = new SparseArray<>();
    traverseManagers(getSupportFragmentManager(), managers, 0);
    if (managers.size() > 0) {
        managers.valueAt(managers.size() - 1).popBackStackImmediate();
    } else {
        super.onBackPressed();
    }
}

private void traverseManagers(FragmentManager manager, SparseArray<FragmentManager> managers, int intent) {
    if (manager.getBackStackEntryCount() > 0) {
        managers.put(intent, manager);
    }
    if (manager.getFragments() == null) {
        return;
    }
    for (Fragment fragment : manager.getFragments()) {
        if (fragment != null) traverseManagers(fragment.getChildFragmentManager(), managers, intent + 1);
    }
}
like image 31
MatrixDev Avatar answered Sep 17 '22 18:09

MatrixDev