Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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);
        }
like image 569
RED_ Avatar asked Jan 13 '14 14:01

RED_


2 Answers

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.

like image 80
vipul mittal Avatar answered Nov 02 '22 05:11

vipul mittal


Just wanted to report my findings even though this question is a little old for anyone else who may have had the same problem with the accepted answer. For me, doing the method suggested in the accepted answer, made the layers overlap, quickly making them unreadable. The code below (adapted from the accepted answer) avoids the overlaying but still adds the screen to the back stack.

fragmentManager.beginTransaction().replace(R.id.container, fragment).addToBackStack("fragBack").commit();
like image 6
Kyle Avatar answered Nov 02 '22 03:11

Kyle