Home » Android » java – Clear Fragment Backstack except top fragment-Exceptionshub

java – Clear Fragment Backstack except top fragment-Exceptionshub

Posted by: admin February 26, 2020 Leave a comment

Questions:

In my app I have some menu items in a Navigation Drawer. When the user taps one of these items and navigates to the corresponding fragment, I want the fragment backstack to be cleared EXCEPT for the fragment they just navigated to. Let me illustrate:

In my nav drawer the user has options to open fragments F1, F2, F3, F4, F5, F6. When the app is first opened, the user starts on F1. Let’s say from F1, the user opens fragments F7 -> F8 -> F9 -> F10 using buttons within the fragment views themselves. At this point, the backstack looks like:

F1 -> F7 -> F8 -> F9 -> F10

Suppose from here, the user opens the nav drawer and selects F2. What I want to happen is that the above backstack is cleared and is populated with ONLY F2, so that they user can’t go back to F10 from F2. In otherwords, the backstack should become:

Not this: F1 -> F7 -> F8 -> F9 -> F10 -> F2
But this: F2

How can I accomplish this?

EDIT 1:
One of my attempted solutions was to add an OnNavigationItemSelectedListener to the navigationView when the activity is loading that would clear the backstack when one of the items was pressed. My solution worked, but in the process I overrode the default code that actually changes to the new fragment. I snooped through the Android API and found this:

navigationView.setNavigationItemSelectedListener(
    new NavigationView.OnNavigationItemSelectedListener() {
    @Override
    public boolean onNavigationItemSelected(@NonNull MenuItem item) {
        boolean handled = onNavDestinationSelected(item, navController);
        if (handled) {
            ViewParent parent = navigationView.getParent();
            if (parent instanceof DrawerLayout) {
                ((DrawerLayout) parent).closeDrawer(navigationView);
            } else {
                BottomSheetBehavior bottomSheetBehavior =
                                    findBottomSheetBehavior(navigationView);
                if (bottomSheetBehavior != null) {
                     bottomSheetBehavior.setState(BottomSheetBehavior.STATE_HIDDEN);
                }
            }
        }
        return handled;
    }
});

This is NOT my code. This is the native code that handles selection of menu items on the navigation drawer (found in the NavigationUI class). If I want to add my own OnNavigationItemSelectedListener I would have to recreate the functionality shown above, which I can’t do since some of the methods in there are protected. So that’s why I don’t believe this solution will work.

How to&Answers:

You can try to clear fragments which are in backstack

FragmentManager manager = getSupportFragmentManager();
if (manager.getBackStackEntryCount() > 0) {
    FragmentManager.BackStackEntry first = manager.getBackStackEntryAt(0);
     manager.popBackStack(first.getId(), FragmentManager.POP_BACK_STACK_INCLUSIVE);
}

Answer:

I hope you are setting all this fragment in the same activity. If yes, then it will not be very hard to achieve whatever you want to achieve.

Make sure whenever you set your fragment in suppose MainActivity, follow this code.

val fragmentTransaction = supportFragmentManager.beginTransaction()
if (fragment == null) {
    fragment = Frag2.newInstance()
    fragmentTransaction.replace(R.id.container, fragment, Frag2.TAG)
} else {
    fragmentTransaction.show(fragment)
}
    fragmentTransaction.commit()

Main logic to achieve required behaviour is behind fragmentTransaction.replace().
So, whenever you set another fragment in a container, use replace() rather than add().

So, try this and give me feedback about it.
Happy coding..!