Set toolbar title dynamically using navigation-component
you can add a method for updating the fragment title and call it in fragment onStart() method
fun updateToolbarTitle(title: String) {
supportActionBar?.title = title
}
and remove lable attribute from tag in your nav_graph.xml so it'll be like that
<fragment
android:id="@+id/myFragment"
android:name=".MyFragment"/>
In case you are passing a custom Object
as parameter, you can use navController.addOnDestinationChangedListener
.
navController.addOnDestinationChangedListener(new NavController.OnDestinationChangedListener() {
@Override
public void onDestinationChanged(@NonNull NavController controller, @NonNull NavDestination destination, @Nullable Bundle arguments) {
Log.i(TAG, "onDestinationChanged");
switch (destination.getId()) {
case R.id.mainFragment:
updateToolbarAndBottomNavigation("Main Title", "Main Subtitle", View.VISIBLE);
break;
case R.id.shopFragment:
updateToolbarAndBottomNavigation("custom title", null, View.VISIBLE);
break;
case R.id.shopcartFragment:
StoreEntity store = (StoreEntity) arguments.get("storeEntity");
Log.i(TAG, "onDestinationChanged: ShopCartFragment args: "+store.getName());
updateToolbarAndBottomNavigation(store.getName(), null, View.GONE);
break;
}
}
});
private void updateToolbarAndBottomNavigation(String title, String subtitle, int visibility) {
getSupportActionBar().setTitle(title);
getSupportActionBar().setSubtitle(subtitle);
bottomNavigationView.setVisibility(visibility);
}
Where the arguments.get()
was retrieved from android:name
in the nav_graph.xml
.
<fragment
android:id="@+id/shopcartFragment"
android:name="com.myapp.ShopcartFragment"
tools:layout="@layout/fragment_shopcart" >
<argument
android:name="storeEntity" // GET ARGUMENTS NAME HERE
app:argType="com.myapp.LocalDatabase.StoreEntity" />
</fragment>
I hope it can help more people!
Navigation supports arguments in labels as of Navigation 1.0.0-alpha08 or higher:
Destination labels, when used with NavigationUI methods, will now automatically replace
{argName}
instances in yourandroid:label
with the correct argument b/80267266
Therefore you can set your label to android:label="{dynamicTitle}"
, then pass in an argument to your navigate
call. As you're using Safe Args, you'd want to add an argument to your destination:
<fragment
android:id="@+id/myFragment"
android:name=".MyFragment"
android:label="{dynamicTitle}">
<argument
android:name="dynamicTitle"
app:argType="string"/>
</fragment>
Then pass in your dynamic title when constructing your directions:
val directions = YourDirections.actionToMyFragment(someTitle)
it.findNavController().navigate(directions)
Of course, you can listen for navigation events yourself and use your own OnDestinationChangedListener
to do whatever you want, including setting the label to whatever you want. There's no requirement to use NavigationUI and any listener to add after calling the NavigationUI methods will override whatever it sets.