Android Navigation Component - Setting HasOptionsMenu invalidates NavigateUp button

Viewed 280

I'm using Android Navigation Component with a bottomNavigationView. I have configured the AppBar in my MainActivity so that a Navigate Up Button appears when the app is not on the start destination of the graph.

I have set SupportedActionBar and override onSupportNavigateUp like so:

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    binding = ActivityMainBinding.inflate(layoutInflater)
    setContentView(binding.root)
    setSupportActionBar(binding.mainToolbar)

    ...

    val controller = binding.bottomNavView.setupWithNavController(
        navGraphIds = navGraphIds,
        fragmentManager = supportFragmentManager,
        containerId = R.id.nav_host_container,
        intent = intent
    )

    controller.observe(this, Observer { navController ->
        appBarConfiguration = AppBarConfiguration(
            topLevelDestinationIds = setOf(
                navController.graph.startDestination,
                R.id.navigation_level_up_onboarding
            )
        )

        setupActionBarWithNavController(navController, appBarConfiguration)
    })
    currentController = controller
}

override fun onSupportNavigateUp(): Boolean {
    return currentController?.value?.navigateUp() ?: false
}

In the navigation graph I have a destination ProfileSettingsFragment which needs to have menu options. I have set them like so:

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)
    setHasOptionsMenu(true)

    ....
}

override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
    inflater.inflate(R.menu.profile_settings_menu, menu)
    super.onCreateOptionsMenu(menu, inflater)
}

Menu options are working fine, but, the navigateUp button stops working for this fragment as soon as I call setHasOptionsMenu(true).

What am I doing wrong? What is the proper way to add menu options on a fragment while keeping navigateUp behaviour when using Navigation Component?

2 Answers

Since you are using a Toolbar instead of

setupActionBarWithNavController(navController, appBarConfiguration)

you can use

toolbar.setupWithNavController(navController, appBarConfiguration)

and you do not need to override the onSupportNavigateUp() method.

This works fine with me. While using actionbar in onOptionsItemSelected() add this check for the up button being clicked/pressed.

In kotlin:

override fun onOptionsItemSelected(item: MenuItem): Boolean {
        when (item.itemId) {
            android.R.id.home->
                requireActivity().onBackPressed() 
          ....//rest of your code
    }

while in java:

@Override
public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        case android.R.id.home :
            getActivity().onBackPressed();
            break;
        ....//rest of your code
}
Related