0

I can not update NavDestination's label at runtime. it reflects but not from the first time i enter the screen, it doesn't reflected instantaneously

My ViewModel

class PrepareOrderDetailsViewModel(
    brief: MarketHistoryResponse,
    private val ordersRepository: OrdersRepository
) : BaseViewModel() {

    private val _briefLiveData = MutableLiveData(brief)

    val orderIdLiveData: LiveData<Int?> =
        Transformations.distinctUntilChanged(Transformations.map(_briefLiveData) { it.id })
}

LiveData observation in the fragment

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        registerObservers()
    }

    private fun registerObservers() {
        viewModel.orderIdLiveData.observe(viewLifecycleOwner, Observer {
            findNavController().currentDestination?.label = getString(R.string.prepare_order_details_title, it)
        })
    }
shaarawy
  • 169
  • 7

2 Answers2

1

As per the Navigation UI documentation, the NavigationUI methods, such as the setupActionBarWithNavController() method rely on an OnDestinationChangedListener, which gets called every time you navigate() to a new destination. That's why the label is not instantly changed - it is only updated when you navigate to a new destination.

The documentation does explain that for the top app bar:

the label you attach to destinations can be automatically populated from the arguments provided to the destination by using the format of {argName} in your label.

This allows you to update your R.string.prepare_order_details_title to be in the form of

<string name="prepare_order_details_title">Prepare order {orderId}</string>

By using that same argument on your destination, your title will automatically be populated with the correct information.

Of course, if you don't have an argument that you can determine ahead of time, then you'd want to avoid setting an android:label on your destination at all and instead manually update your action bar's title, etc. from that destination.

ianhanniballake
  • 191,609
  • 30
  • 470
  • 443
  • thanks @ianhanniballak it works fine now but it will be great if we managed to get a new feature in the navigation library to make it like below `Order Number {orderBrief.id}` – shaarawy May 18 '19 at 21:02
  • @MohamedElshaarawy - there's no plans to use reflection to access methods in generic objects, nor force you to keep specific field names on those objects. That'd be pretty bad on multiple levels. – ianhanniballake May 18 '19 at 22:29
0

I reach to a workaround for that issue by accessing the SupportActionBar itself and set the title on label behalf

    private fun registerObservers() {
        viewModel.orderIdLiveData.observe(viewLifecycleOwner, Observer {
            (activity as AppCompatActivity).supportActionBar?.title =
                getString(R.string.prepare_order_details_title, it)

        })
    }
shaarawy
  • 169
  • 7