Navigation drawer, handling the back button to go to previous fragments?

RED_ picture RED_ · Jan 13, 2014 · Viewed 42.6k times · Source

I'm using the built-in navigation drawer to run my app. I can't quite figure out how to handle the back button. When it's pressed I want it to load the very first fragment again. Fragment1.

So when the app launches you see Fragment1 launched. They can then click on Fragment 2-5 to go to other pages. Within all of these pages, I want the back button to take the user back to Fragment1. The only place the user should be able to exit the app via the back button is Fragment1.

Since it's all handled by a FragmentActivity I tried messing with the back button there. I keep getting a force close error, however:

(01-11 14:09:33.114: E/AndroidRuntime(8292): android.view.InflateException: Binary XML file line #7: Error inflating class fragment)

This is what I have so far:

I've made sure to add the fragments to the back stack like this:

fm.beginTransaction().replace(R.id.main, newFragment).addToBackStack("fragBack").commit();

Back button:

@Override
public void onBackPressed() {
    if (getSupportFragmentManager().findFragmentByTag("fragBack") != null) {
        
    }
    else {
        super.onBackPressed();
        return;
    }
    if (getSupportFragmentManager().getBackStackEntryCount() != 0) {
        Toast.makeText(getApplicationContext(), "Test", Toast.LENGTH_LONG).show();
        Fragment frag = getSupportFragmentManager().findFragmentByTag("fragBack");
        FragmentTransaction transac = getSupportFragmentManager().beginTransaction().remove(frag);
                transac.commit();
    }
    
}

Does anyone know what I need to do? Do I need to call onBackPressed in every fragment (if that's even possible) rather than the FragmentActivity that controls the drawer? In my past apps I've been OK with the back button closing the app regardless of which Fragment the user is on but the one I'm making now I want the back button to go back to Fragment1.

Would really appreciate some help, thank you.

onItemClick

@Override
        public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
            
            Fragment newFragment = new MapsPage();
            FragmentManager fm = getSupportFragmentManager();
            switch(i) {
            case 0:
                newFragment = new Fragment2();
                break;
            case 1:
                newFragment = new Fragment3();
                break;
            case 2:
                newFragment = new Fragment4();
                break;
            case 3:
                newFragment = new Fragment5();
                break;
            }
            fm.beginTransaction().add(R.id.main, newFragment).addToBackStack("fragback").commit();
            drawerLayout.closeDrawer(rl);
        }

Answer

vipul mittal picture vipul mittal · Jan 13, 2014

Instead of:

fm.beginTransaction().replace(R.id.main, newFragment).addToBackStack("fragBack").commit();

Call:

fm.beginTransaction().add(R.id.main, newFragment).addToBackStack("fragBack").commit();

addToBackStack works with add.

replace function removes previous fragment and places new fragment so on your back-stack there is only one fragment all the time. So use add function to keep previous fragments on stack.

To always goto fragemnt1 from any fragment onBackPress try to do following:

getFragmentManager().popBackStack();
fm.beginTransaction().add(R.id.main, newFragment).addToBackStack("fragBack").commit();

this will remove last transaction from backstack and add new one. Try this.