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

0
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)
}
5
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
On

Try This,

Fragment fragment= new ChildFragment1();
getChildFragmentManager().beginTransaction().replace(R.id.contentView, fragment).addToBackStack(fragment.getClass().getName()).commitAllowingStateLoss();
1
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();
}