I've got a custom settings screen that recursively can create views based on config. The navigation of this mostly works fine. It's embedded in an Activity, Activity B.
To handle the recursive nature of the fragments, I update the values in a recycler view every time a next or previous fragment is navigated to. Again, this all works fine.
To get to the settings, I navigate from Activity A to Activity B using the navigation component.
Here is an image of Activity A, and the settingsFragment (really, activity B) in the navigation graph, if it helps clarify this setup:
Note the settingsFragment goes into itself.
I need the previous settings lists to load as I go back through the settings until the user reaches the top-level one. The problem I'm facing is, back navigation from the settings (SettingsFragment in Activity B), to Activity A is quite flakey. Initially, that is just when opening SettingsFragment, it works. But the further into nested settings menus you go, then an equal number of taps of the back button are required to get from the top SettingsFragment to ActivityA. So 3 levels down require 3 back button presses at the top settings level (totaling 5 or 6 taps up).
I think this is a problem to do with my custom back navigation code, which I need to change data in the ViewModel. But it's overwriting standard back navigation to Activity A. I thought I fixed this by trying to call requireActivity().onBackPressed()
at the appropriate time. So that's where I'm at now.
Here's the relevant code:
val callback: OnBackPressedCallback =
object : OnBackPressedCallback(true) {
override fun handleOnBackPressed() {
viewModel.onBackPressed()
if (viewModel.currentMenuId == null) {
isEnabled = false // Have to set this to false otherwise onBackPressed below begins an infinite loop.
requireActivity().onBackPressed()
}
}
}
requireActivity().onBackPressedDispatcher.addCallback(
viewLifecycleOwner,
callback
)
I guess I don't understand how this should work if I'm re-using a fragment. Should I have a callback for each instance? And if so, how do I disable it at the top, correctly?