Remove up button from action bar when navigating using BottomNavigationView with Android Navigation UI library
Asked Answered
A

6

30

I've created a small app that has three fragments for top-level navigation through a BottomNavigationView. If you launch the app and click on a navigation button on the bottom nav, you are presented with an up button in the action bar. Here is the code for the activity:

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.main_activity)

        setSupportActionBar(toolbar)

        val navController = navHostFragment.findNavController()
        setupActionBarWithNavController(this, navController)
        setupWithNavController(bottomNav, navController)
    }

    override fun onSupportNavigateUp(): Boolean
            = findNavController(navHostFragment).navigateUp()

}

Here is a screenshot of the result. The app is launched on the home screen and all I've done is simply click the profile button from the BottomNavigationView.

enter image description here

I've tried listening to the BottomNavigationView's item selections and navigating manually using different NavOptions to no avail. Is there anything we can do to avoid showing an up button in the action bar while the user is navigating with a BottomNavigationView?

Aborning answered 12/5, 2018 at 0:31 Comment(0)
R
51

Starting with 1.0.0-alpha07 you can use AppBarConfiguration to configure that behaviour.

AppBarConfiguration has a Builder constructor so you can create a new Builder with a specific set of top level destinations, referenced by their id (this id is the one you set on your navigation layout).

Create new AppBarConfiguration:

val appBarConfiguration = AppBarConfiguration
            .Builder(
                    R.id.navigationHomeFragment,
                    R.id.navigationListFragment,
                    R.id.navigationProfileFragment)
            .build()

Then, instead of setupActionBarWithNavController(this, navController) you need to call setupActionBarWithNavController(this, navController, appBarConfiguration)

This is the right way to handle top navigation behaviours.

Rudy answered 25/11, 2018 at 1:11 Comment(5)
Uh, okay this component is like magic now I don't know wtf is going on :)Jesu
Great solution (Y)Gelatin
Saved the day :) ThanksConfirmand
Thanks. But starting with 1.0.0 I had to call setupWithNavController( navController, appBarConfiguration) to make it workPleione
thank you , great solution to hide Up Navigation for some fragmentsPajamas
I
12

I had the same problem and I found a way to get the current fragment with the NavController.addOnNavigatedListener, so I applied the following logic within my Activity and for now it works for me

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_home)
    val navHost = supportFragmentManager
            .findFragmentById(R.id.navHostFragment) as NavHostFragment

    navHost.navController.addOnNavigatedListener { _, destination ->
        val showButton = showUpButton(destination.id)
        //Here occurs the magic
        supportActionBar?.setDisplayShowHomeEnabled(showButton)
        supportActionBar?.setDisplayHomeAsUpEnabled(showButton)
    }
}

//Check according to your convenience which fragment id
//should show or hide the "Up Button"
private fun showUpButton(id: Int): Boolean {
    return id != R.id.your_home_fragment && id != R.id.your_list_fragment 
            && id != R.id.your_profile_fragment
}

And this is my project...

enter image description here

I do not know if it is the best option but if someone has any better suggestion, it will be welcome

Indistinctive answered 18/5, 2018 at 21:7 Comment(0)
S
5

Use this instead of setupWithNavController:

navController.addOnNavigatedListener(new NavController.OnNavigatedListener() {
     @Override
     public void onNavigated(@NonNull NavController controller, @NonNull NavDestination destination) {
         toolbar.setTitle(destination.getLabel());
     }
});

Or the equivalent in Kotlin.

The only thing setupWithNavController does is add a listener to change the toolbar title, and creates the up button. If you don't want the up button, just add a listener which changes the toolbar title only.

Salonika answered 20/9, 2018 at 18:43 Comment(2)
Thanks Bob, this solved my problem. People like you are why I love Stackoverflow.Billings
keep in mind that the addOnNavigatedListener has been changed to addOnDestinationChangedListener in new version of navigation componentMidriff
H
2

You could set the navigation icon to null, or change the icon only for some destinations eg:

1) In Kotlin:

navController.addOnDestinationChangedListener { _, destination, _ ->
            toolbar.title = destination.label
            toolbar.navigationIcon = null
}

2) In Java:

hostFragment.getNavController().addOnDestinationChangedListener(new OnDestinationChangedListener() {
    public final void onDestinationChanged(@NotNull NavController controller, @NotNull NavDestination destination, @Nullable Bundle arguments) {
        toolbar.setTitle(destination.getLabel());
        toolbar.setNavigationIcon(null);
    }
});
Herring answered 3/5, 2020 at 13:44 Comment(0)
T
1

If you are using NavigationUI.setupWithNavController check out onNavDestinationSelected.

Inside your bottom navigation view menu.xml, add android:menuCategory="secondary" to the corresponding MenuItem:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">

  <item
    android:id="@+id/profileFragment"
    android:icon="@drawable/bottom_nav_icon_profile"
    android:menuCategory="secondary"
    android:title="@string/profile" />
Tempest answered 12/6, 2019 at 14:10 Comment(1)
Applying the android:menuCategory="secondary" attribute to the items in the bottom navigation menu.xml does not hide the up-button in my case. I was able to hide it by applying the AppBarConfiguration as suggested by Javier Cancio. - Setting secondary however has the effect that when BACK is pressed the navigation returns to the previous bottom navigation element (having 3 or more). Without secondary always the primary element will be navigated to. Is there anything I am missing with your answer?Lajoie
A
0

In Java this works for me:

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

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

    navController = Navigation.findNavController(this, R.id.nav_host_fragment);
    AppBarConfiguration appBarConfiguration = new AppBarConfiguration
            .Builder(navController.getGraph())
            .build();
    NavigationUI.setupWithNavController(toolbar, navController, appBarConfiguration);

    navController.addOnDestinationChangedListener((controller, destination, arguments) -> {
        toolbar.setTitle(destination.getLabel());
        toolbar.setNavigationIcon(null);
    });
Amathist answered 21/10, 2020 at 17:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.