I was trying out Navigation architecture component and is now having difficulties in setting the title. How do I set the title programmatically and also how it works?
<As others are still participating in answering this question, let me answer my own question as APIs has changed since then.
First, remove android:label
from the fragment/s that you wish to change the title of, from within navigation.xml
(aka Navigation Graph),.
Now you can change the title from with the Fragment
by calling
(requireActivity() as MainActivity).title = "My title"
But the preferred way you should be using is the API NavController.addOnDestinationChangedListener from within MainActivity
. An Example:
NavController.OnDestinationChangedListener { controller, destination, arguments ->
// compare destination id
title = when (destination.id) {
R.id.someFragment -> "My title"
else -> "Default title"
}
// if (destination == R.id.someFragment) {
// title = "My title"
// } else {
// title = "Default Title"
// }
}
You can use the navigation graph xml file and set the label of the fragment to an argument. Then, in your parent fragment, you can pass an argument using SafeArgs and provide a default value to avoid the title being null or empty.
<!--set the fragment's title to characters name passed as an argument-->
<fragment
android:id="@+id/characterDetailFragment2"
android:name="ui.character.CharacterDetailFragment"
android:label="{character_name}"
tools:layout="@layout/fragment_character_detail">
<argument
android:name="character_name"
android:defaultValue="Name"
app:argType="string" />
</fragment>
In originating Fragment:
String text = "text to pass";
CharactersListFragmentDirections.CharacterDetailAction action = CharactersListFragmentDirections.characterDetailAction();
action.setCharacterName(text);
Navigation.findNavController(v).navigate(action);
CharactersListFragmentDirections and CharacterDetailAction - These classes are autogenerated from IDs in your nav_graph.xml file. In 'your action ID + Action' type classes you can find auto-generated setter methods, which you can use to pass arguments
<fragment
android:id="@+id/charactersListFragment"
android:name=".character.CharactersListFragment"
android:label="List of Characters"
tools:layout="@layout/fragment_characters_list">
<action
android:id="@+id/characterDetailAction"
app:destination="@id/characterDetailFragment2"
app:enterAnim="@anim/slide_in_right"
app:exitAnim="@anim/slide_out_left"
app:popEnterAnim="@anim/slide_in_left"
app:popExitAnim="@anim/slide_out_right" />
</fragment>
In your receiving destination (xml layout file is at the top of this answer) you call auto generated class {your receiving fragment ID}+Args
CharacterDetailFragmentArgs.fromBundle(requireArguments()).getCharacterName();
Please refer to official guide https://developer.android.com/guide/navigation/navigation-pass-data#Safe-args
Another approach could be this:
fun Fragment.setToolbarTitle(title: String) {
(activity as NavigationDrawerActivity).supportActionBar?.title = title
}
I would suggest to include AppBar in each screen. To avoid code duplicates, create a helper, that builds AppBar, taking the title as a parameter. Then invoke the helper in each screen class.
delete detatil fragment's label in navigation graph xml file.
then pass the prefered title through arguments to destination fragment which needs title like so.
The First Fragment code - Start point
findNavController().navigate(
R.id.action_FirstFragment_to_descriptionFragment,
bundleOf(Pair("toolbar_title", "My Details Fragment Title"))
)
as you see I sent as pair in arguments bundle when navigating to Destination Fragment
so in your Destination Fragment get title from arguments in onCreate method like this
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
toolbarTitle = requireArguments().getString("toolbar_title", "")
}
requireActivity().toolbar.title = toolbarTitle
The API may have changed since the question was asked, but now you may indicate a reference to a string in your app resources in the navigation graph label.
This is pretty helpful if you want a static title for your fragments.