How to set title in app bar with Navigation Architecture Component

前端 未结 12 1984
面向向阳花
面向向阳花 2020-12-24 11:40

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?

<
相关标签:
12条回答
  • 2020-12-24 12:35

    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"        
    //    }
    }
    
    0 讨论(0)
  • 2020-12-24 12:36

    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

    0 讨论(0)
  • 2020-12-24 12:36

    Another approach could be this:

    fun Fragment.setToolbarTitle(title: String) {
        (activity as NavigationDrawerActivity).supportActionBar?.title = title
    }
    
    0 讨论(0)
  • 2020-12-24 12:37

    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.

    0 讨论(0)
  • 2020-12-24 12:40

    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", "")
        }
    

    then use it to change Main Activity's title in onCreateView method like this
    requireActivity().toolbar.title = toolbarTitle
    

    0 讨论(0)
  • 2020-12-24 12:43

    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.

    0 讨论(0)
提交回复
热议问题