3

I am using a DrawerLayout with and adding a new Fragment each time the user taps an item from the drawer menu. This works perfectly.

Within one of those fragments the user can navigate to another fragment:

private void loadArchives() {

    PUCNewsArchive news_archive = new PUCNewsArchive();

    getFragmentManager()
    .beginTransaction()
    .add(R.id.container_frame, news_archive, "news_archives")
    .addToBackStack(null)
    .commit();

}

This will correctly add another fragment to the stack. BUT, it does not change the action bar drawer button/icon to a back button. So, in tapping that just opens the drawer again, which is should not do. The only way to navigate back is the use the hardware back button which does go back to the previous fragment. I tried adding the following to my main Activity to see what was going on:

@Override
public void onBackPressed(){
    FragmentManager fm = getFragmentManager();
    if (fm.getBackStackEntryCount() > 0) {
        Log.i("MainActivity", "popping backstack");
        fm.popBackStack();
    } else {
        Log.i("MainActivity", "nothing on backstack, calling super");
        super.onBackPressed();
    }
}

But that is only ever called when I use the hardware back button, as the drawer button is only ever opening the drawer.

I assume this should be checking to see if it should open the drawer or navigate:

@Override
public boolean onOptionsItemSelected(MenuItem item) {

    if (mDrawerToggle.onOptionsItemSelected(item)) {
        return true;
    }

    switch(item.getItemId()) {
    case android.R.id.home:

        return true;
    default:
        return super.onOptionsItemSelected(item);
    }

}

What have I missed? Why is the drawer button never changing to a back button nor acting like one?

Nic Hubbard
  • 41,587
  • 63
  • 251
  • 412
  • possible duplicate of [Using DrawerLayout with Fragments and getting up navigation working](http://stackoverflow.com/questions/25145995/using-drawerlayout-with-fragments-and-getting-up-navigation-working) – tyczj Aug 06 '14 at 17:40
  • @Spurdow No I have that in `onPostCreate`. – Nic Hubbard Aug 06 '14 at 17:43
  • @FrankN.Stein I don't have a child of the main activity. I only have a Main activity and then fragments. So no, I have not added anything to my manifest about the parent activity. – Nic Hubbard Aug 06 '14 at 17:58

3 Answers3

2

You don't need to use the onBackPressed().

I had a very similar situation in my app. Here is how I got it to work:

I created a method in the main activity:

public void foo(int fragment_id) {
        if(fragment_id == some_id){
            // keep the drawer carat
            mDrawerToggle.setDrawerIndicatorEnabled(true);
        }else{
            // Disable the  drawer carat, and enable the back button
            mDrawerToggle.setDrawerIndicatorEnabled(false);
            getActionBar().setDisplayHomeAsUpEnabled(true);
        }
    }

I call this method from onResume() of each fragment, and pass it that particular fragments id. Alternatively, you can call it from the loadFragment()/loadArchives() method in your main activity. This works fine for me.

Community
  • 1
  • 1
rgamber
  • 5,749
  • 10
  • 55
  • 99
  • But what about making it pop the current fragment off the stack when I tap that button? – Nic Hubbard Aug 06 '14 at 18:13
  • Ah, yes. Sorry I forgot to mention that. When you load the fragment, give it a name/id. And when you press the back button you can call the `fm.popBackStack("name"/id, FragmentManager.POP_BACK_STACK_INCLUSIVE)`. – rgamber Aug 06 '14 at 18:20
  • And what function is called each time that back/drawer icon is tapped? – Nic Hubbard Aug 06 '14 at 18:22
  • In my case, I have a 'home page`. Whenever the user selects this item from the drawer, in my `onOptionsItemSelected()` in the main activity, I call `if (fm.getBackStackEntryCount() > 0) { fm.popBackStack(); }`. So it clears the entire stack when the user goes back to the home page. You can probably use a similar arrangement? (In my app there are only 2 levels. So I don't need to call the fragment by name/id.) – rgamber Aug 06 '14 at 18:27
  • Thanks. The Android navigation structure drives me nuts. When building iOS apps this would have taken me 5 minutes. :( – Nic Hubbard Aug 06 '14 at 18:37
  • 1
    Indeed! I spent so much time on Android Documentation + StackOverflow.com when I was implementing this. There is no single place where I could get all the information! Its scattered all over. Though I'm glad it works for you now! – rgamber Aug 06 '14 at 18:43
0

In your Navigation Activity

This activity controls all fragments in the app.

When preparing new fragments to replace others, I set the DrawerToggle setDrawerIndicatorEnabled(false) like this:

private void loadArchives() {

PUCNewsArchive news_archive = new PUCNewsArchive();

//disable the toggle menu and show up carat
theDrawerToggle.setDrawerIndicatorEnabled(false);

getFragmentManager()
.beginTransaction()
.add(R.id.container_frame, news_archive, "news_archives")
.addToBackStack(null)
.commit();
}

in onCreateview of another fragment

call

// update the actionbar to show the up carat/affordance getActivity().getActionBar().setDisplayHomeAsUpEnabled(true);

For More reference Check This Question

Community
  • 1
  • 1
Ando Masahashi
  • 3,112
  • 2
  • 24
  • 41
  • 1
    Ok, so that works great to show the back button when I want to. But what about making it pop the current fragment off the stack when I tap that button? – Nic Hubbard Aug 06 '14 at 18:09
0

I tried above suggested codes But the "up" or "Back" arrow in left side of action bar was just not showing up in my app. But luckily I was able to fix that.

Brief code:

Function to start fragment while putting the current fragment to Back Stack:

public void startFragment(){
    MyFrag myFrag = new MyFrag();

    getSupportFragmentManager()
        .beginTransaction()
        .replace(R.id.frag_container ,myFrag)
        .addToBackStack(null)
        .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE)
        .commit();
}

Function to turn ON or OFF "NavigationDrawer":

public void setNavigationDrawerState(boolean isEnabled) {
if ( isEnabled ) {
    drawer.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED);
    toggle.setDrawerIndicatorEnabled(true);
    toggle.syncState();
}
else {
    drawer.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
    toggle.setDrawerIndicatorEnabled(false);
    toggle.setHomeAsUpIndicator(R.drawable.ic_keyboard_backspace_white_24dp);    

    toggle.syncState();
}

I downloaded the drawable: ic_keyboard_backspace_white_24dp from Material.io

The complete answer:

Disabling navigation drawer, toggling home-button/up-indicator in fragments

Community
  • 1
  • 1
Vinay Vissh
  • 457
  • 2
  • 9
  • 12