1

The back or up button is not working when using a navigation drawer. The icon changes from a hamburger (having set the top level destinations) but both open the navigation drawer. I want the back/up arrow to go back in the stack.

public class MainActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener, DrawerLocker {

public static final String TAG = MainActivity.class.getSimpleName();

private DrawerLayout drawerLayout;
private NavigationView navView;
private Toolbar toolbar;

private NavController navController;
private ActionBarDrawerToggle drawerToggle;


private AppBarConfiguration appBarConfiguration;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    toolbar = findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);


    //configure drawer layout
    drawerLayout = findViewById(R.id.drawer_layout);
    navView = findViewById(R.id.drawer_navigation_view);

    navController = Navigation.findNavController(this,R.id.nav_host_fragment);

    appBarConfiguration = new AppBarConfiguration.Builder(R.id.scenarioListFragment,
            R.id.tokenListFragment, R.id.settingsFragment,R.id.historyFragment)
            .setDrawerLayout(drawerLayout)
            .build();

    NavigationUI.setupActionBarWithNavController(this, navController, appBarConfiguration);
    NavigationUI.setupWithNavController(navView, navController);

    navView.setNavigationItemSelectedListener(this);

    drawerToggle = new ActionBarDrawerToggle(this, drawerLayout, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);

    drawerLayout.addDrawerListener(drawerToggle);
    drawerToggle.syncState();

    if (savedInstanceState == null ) {
        navView.setCheckedItem(R.id.drawer_menu_scenario);
        toolbar.setTitle("Scenarios");
    }
}

I watched this video, which made it seem sort of simple, but it is referring to Kotlin and my code is not far off.

This post covers a similar challenge as well, though in Kotlin I tried adding a setNavigationOnClickListener and put a logd statement in it. It never got fired, but the solution itself seemed like it shouldn't be necessary.

This post seems to have cover the same issue but there are no answers. One of the responses says to setupActionBarWithNavController, which I have:

NavigationUI.setupActionBarWithNavController(this, navController, appBarConfiguration);

This function has a lot of overloads and I've tried a number of them, but they seem to cause me to lose the set of top level destinations (hamburger icon for multiple fragments) and undue my the navigation which is working.

I tried to follow this documentation, but it only seemed to step me back from where I was. This call:

    AppBarConfiguration appBarConfiguration =
            new AppBarConfiguration.Builder(navController.getGraph())
                    .setDrawerLayout(drawerLayout)
                    .build();

Seems to replace the topLevelDestinations and use the navController.getGraph(), but since I have multiple ones, I have been referencing the fragments themselves.

I did ask about this problem previously but it was clear to me I did not explain it well (answers addressed how to pop back and not why the back arrow was not working). I would have deleted it but people did answer and the guidance SO provided was that I should not delete it in that case. I am sorry if I caused confusion.

lcj
  • 1,355
  • 16
  • 37

1 Answers1

2

There's two issues:

  1. As per the Add a navigation drawer documentation:

When using NavigationUI, the top app bar helpers automatically transition between the drawer icon and the Up icon as the current destination changes. You don't need to use ActionBarDrawerToggle.

So you must remove all of your ActionBarDrawerToggle code.

  1. As per the Setting up the Action bar documentation:

override onSupportNavigateUp() to handle Up navigation:

@Override
public boolean onSupportNavigateUp() {
    NavController navController = Navigation.findNavController(this,
            R.id.nav_host_fragment);
    return NavigationUI.navigateUp(navController, appBarConfiguration)
            || super.onSupportNavigateUp();
}

Note that your if (savedInstanceState == null) is also unnecessary if you've included an android:label on your destinations and are using setupWithNavController.

ianhanniballake
  • 191,609
  • 30
  • 470
  • 443
  • I have one area of my app in which I need the drawer and the back/up button to be disabled and not visible. How would you recommend doing that? – lcj Aug 22 '20 at 22:25
  • That seems like precisely what the `OnDestinationChangedListener` was built for as per the [Listen for navigation events documentation](https://developer.android.com/guide/navigation/navigation-ui#listen_for_navigation_events) – ianhanniballake Aug 22 '20 at 22:51
  • Removing the `ActionBarDrawerToggle` code did it for me. In the process of migrating I didn't realize this wasn't needed any more and now the back arrow works. – Eric B. Aug 19 '22 at 01:33