addOnDestinationChangedListener not called for global actions

Viewed 3585

My app uses the navigation controller for navigation as well as a navigation drawer. I need to detect when one particular menu item in the navigation drawer is clicked. Implementing a typical navigation view listener will not work as this messes with the navigation controller's own listeners. Instead, the navigation controller has the addOnDestinationChangedListener that I can use to detect when destinations change:

navController.addOnDestinationChangedListener { _, destination, _ ->

}

This works if I am navigating to a fragment but it will not work if the navigation uses a global action. I need the global action because the menu item takes the user from the current activity to another activity. The navigation controller does in fact take me to the other activity, but the addOnDestinationChangedListener is never called. I need to detect when the other activity is about to be called.

2 Answers

I stumbled upon a similar issue recently. I was calling controller.navigate() on a non-UI thread. And although navigation action did execute, the destination listener was never triggered. Enforcing the navigate call execution on the main thread resolved all my issues.

It's hard to say for sure without seeing how your NavController and NavHost are initialized but I assume that you're using NavHostFragment as the officials docs do. Something like this:

<fragment
    android:name="androidx.navigation.fragment.NavHostFragment"
    app:defaultNavHost="true"
    app:navGraph="@navigation/main"
/>

That means your controller is bound to the lifecycle of the NavHostFragment and is destroyed with the activity and thus when you navigate to a new activity. As OnDestinationChanged is only called after the new destination is reached you never get notified becaue the NavController that you added your listener to is destroyed before the navigation is complete.

To get a global controller you'll need to make your own using applicationContext as the javadoc for NavController suggests: https://developer.android.com/reference/kotlin/androidx/navigation/NavController.html#init (otherwise you'll have memory leak as it stores the supplied Context).

Related