Search code examples
androidfragmentback-stackfragmenttransactionfragment-backstack

Manage the backstack in android


Currently the structure of the android app is

Home
   About us
   Products
     product1
     product2
     product3
   Contact us

As there is a side-menu and I can access the product 1 directly, My current attempt is add to backstack for every transaction,and it has a behavior that is quite strange

If I go into like this:

Home->product1->About us

The flow is after I enter the home page, I click on the product1 on the side menu, after enter product1 page click on the about us on the side menu

1st time press back button, it will go back to product1, but it should go to home

2nd time press back button, it will go to home, but it should go to the Products page

How to handle the backstack in such situation? Thanks for helping.


Solution

  • You're going to need to be smart when you are changing the fragments and popBackStack at the appropriate times in order to control the stack. Here's an example from one of my applications (also handles reusing existing fragments in the stack):

    // Idea from http://stackoverflow.com/questions/18305945/how-to-resume-fragment-from-backstack-if-exists
    private void setPrimaryContentFragment(BaseFragment fragment, boolean allowStack){
        final String backStackName = fragment.getBackStackName();
    
        final FragmentManager manager = getSupportFragmentManager();
        final boolean fragmentPopped = manager.popBackStackImmediate(backStackName, 0);
    
        if (!fragmentPopped) { //fragment not in back stack, create it.
            if (!allowStack && manager.getBackStackEntryCount() > 1) {
                manager.popBackStack(manager.getBackStackEntryAt(0).getId(), 0);
            }
    
            final FragmentTransaction transaction = manager.beginTransaction();
            transaction.replace(R.id.primary_content, fragment);
            transaction.addToBackStack(backStackName);
            transaction.commit();
    
            try {
                manager.executePendingTransactions();
            } catch (IllegalStateException exception) {
                // Move along as this will be resolved async
            }
        }
    }
    

    The getBackStack() method is implemented in my base fragment and has a default implementation of:

    public String getBackStackName() {
        return getClass().getName();
    }
    

    The allowStack flag is used to control whether there can be more than one entry in the backstack.

    As far as inserting the Product fragment when a user navigates directly to a detail page you'll likely need to do just that. ie: Execute a replace for Products and then a replace for Product details. Hopefully this code snippet and the linked post will help you come up with the solution you need.