Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamic ActionBar title from a Fragment using AndroidX Navigation

I am using the new Navigation component from Android Jetpack.

The root Activity setup is quite simple:

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    setSupportActionBar(toolbar)

    val navController = findNavController(R.id.navigationFragment)
    setupActionBarWithNavController(navController)

    bottomNavigationView.setupWithNavController(navController)
}

It works well when the Fragment's title is defined in the navigation graph. But for one Fragment, I want to set the title dynamically.

I tried with findNavController().currentDestination.label = "Hello world" but it does nothing.

I could of course use a trick like (activity as? AppCompatActivity)?.supportActionBar?.title = "Hello world", but I feel that it will break the magic that setupActionBarWithNavController() does for me. It there any way to update the Action Bar title dynamically?

like image 446
Jonas Schmid Avatar asked May 30 '18 07:05

Jonas Schmid


3 Answers

As of 1.0.0-alpha08, you can have the NavigationUI bits dynamically set the title... if the dynamic bits are arguments on the navigation action.

So, for example, in your navigation graph, you could have something like this:

  <fragment
    android:id="@+id/displayFragment"
    android:name="com.commonsware.jetpack.sampler.nav.DisplayFragment"
    android:label="Title: {title}" >
    <argument
      android:name="modelId"
      app:argType="string" />
    <argument
      android:name="title"
      app:argType="string" />
  </fragment>

Here, the android:label attribute for our <fragment> has an argument name wrapped in braces ({title} in "Title: {title}". The app bar's title will then be set to the value of the label, with {title} replaced by the value of the title argument.

If you need something more elaborate than that — for example, you want to look up the model by ID and read a property from it — you will need to use more manual approaches, such as those outlined in other answers to this question.

like image 150
CommonsWare Avatar answered Nov 12 '22 16:11

CommonsWare


The title can be changed in the fragment by casting the activity as AppCompatActivity.

Kotlin

(requireActivity() as AppCompatActivity).supportActionBar?.title = "Hello"

Java

((AppCompatActivity) requireActivity()).getSupportActionBar().setTitle("Hello");
like image 42
Patriotic Avatar answered Nov 12 '22 15:11

Patriotic


Taking consideration that your host activity is MainActivity, just add the following code to your MainActivity's onCreate fun

val navController = Navigation.findNavController(this, R.id.nav_host_fragment)

// setting title according to fragment
navController.addOnDestinationChangedListener { 
    controller, destination, arguments ->
        toolbar.title = navController.currentDestination?.label
}
like image 19
Kaustubh Trivedi Avatar answered Nov 12 '22 14:11

Kaustubh Trivedi