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
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);
}
});
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" />
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);
});
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...
I do not know if it is the best option but if someone has any better suggestion, it will be welcome
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.
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.