How to manage Backstack with child fragments?

5.6k Views Asked by At

I am having issues with nested/child fragments. My use case is: I have Frag A as parent fragment and FragChild1, FragChild2, FragChild3 as child fragments to be displayed inside Frag A. Now on back press from FragChild3 it should work like :

FragChild3 -> FragChild2 -> FragChild1 -> FragA(ParentFrag).

The code I used to add child fragments are-

for ChildFrag1-

Fragment mChildFragment1 = new ChildFragment1();
        FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
        transaction.replace(R.id.container_view, mChildFragment1);
        transaction.addToBackStack("FragChild1");
        transaction.commit();
        
for ChildFrag2-

Fragment mChildFragment2 = new ChildFragment2();
        FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
        transaction.replace(R.id.container_view, mChildFragment2);
        transaction.addToBackStack("FragChild2");
        transaction.commit();

I have searched through StackOverflow for relevant answers but haven't yet found any proper answer/way of managing backstack for child fragments.

4

There are 4 best solutions below

5
Prashanth Verma On

Pass the tag into the replace method. TAG can as simple as the fragments name (String). Change your code like this:

transaction.replace(R.id.container_view, mChildFragment1, "FragChild1");
transaction.addToBackStack("FragChild1");
transaction.commit();
0
SHIDHIN TS On

Try This,

Fragment fragment= new ChildFragment1();
getChildFragmentManager().beginTransaction().replace(R.id.contentView, fragment).addToBackStack(fragment.getClass().getName()).commitAllowingStateLoss();
1
Amninder Singh On

Your code seems good. Just override onbackpressed method in activity that contains parent fragment and put given code in it.

if (parentfragment.getChildFragmentManager().getBackStackEntryCount() > 1) {
    parentfragment.getChildFragmentManager().popBackStackImmediate();
} else {
    super.onBackPressed();
}
0
Daniil Pavlenko On

Now this behavior can be implemented with OnBackPressedDispatcher without overriding onBackPressed in an Activity.

In your parent fragment (where your fragment container is located) add this code in onAttach method:

override fun onAttach(context: Context) {
    super.onAttach(context)
    val backCallback = object : OnBackPressedCallback(true) {
        override fun handleOnBackPressed() {
            // Remove all fragments from the childFragmentManager,
            // but exclude the first added child fragment.
            // This child fragment will be deleted with its parent.
            if (childFragmentManager.backStackEntryCount > 1) {
                childFragmentManager.popBackStack()
                return
            }
            // Delete parent fragment
            parentFragmentManager.popBackStack()
        }
    }
    requireActivity().onBackPressedDispatcher.addCallback(this, backCallback)
}

Than add fragments in your container like this:

childFragmentManager.commit {
    replace(R.id.fragmentContainerRoot, fragment)
    addToBackStack(null)
}