In the app, we start a new activity holding a fragment, let's call it A. Recently navigation component was added and transitions follow the navigation graph.
So initially it is started by
navController = findNavController(R.id.nav_host_fragment)
val graphInflater = navController.navInflater
val navGraph = graphInflater.inflate(R.navigation.something_graph)
val startDestination: Int = something
navGraph.startDestination = startDestination
navController.setGraph(navGraph, intent.extras)
Afterward, the user makes some actions, invokes a new fragment, let's say fragment B, and then we need to get back to fragment A.
Currently, this is done by
findNavController().navigate(SomethingGraphDirections.actionGlobalNavSomethingFragment(action, destination))
Unfortunately this causes fragment A (not activity), to be called twice as a new instance, and then delete is called as described similarly to this post.
I can verify it by printing on the log this
statements.
Activity com.sen.osmo.ui.SomethingActivity@aad8485 onCreate
Fragment SomethingFragment{1c32bd3} (325a1bc9-d922-49ff-8d0a-65e35427d109) id=0x7f0901c8} onCreateView
action
Fragment SomethingFragment{fd9bbac} (eedc20a5-49b1-481c-8045-4cd60c427c78) id=0x7f0901c8} onCreateView
Fragment SomethingFragment{1c32bd3} (325a1bc9-d922-49ff-8d0a-65e35427d109) id=0x7f0901c8} onDestroy
normal end of cycle and actions
Fragment SomethingFragment{fd9bbac} (eedc20a5-49b1-481c-8045-4cd60c427c78) id=0x7f0901c8} onDestroy
Activity com.sen.osmo.ui.SomethingActivity@aad8485 onDestroy
Trying the old code instead of findNavController().navigate
solves this issue somewhat. which is
if (fragmentManager!!.backStackEntryCount > 0) {
fragmentManager!!.popBackStack()
} else {
...
}
fragmentManager!!.beginTransaction().remove(this).commitAllowingStateLoss()
The result is on create called twice but on the same instance, and no onDestroy is called.
Activity onCreate com.sen.osmo.ui.SomethingActivity@96035a6
Fragment onCreateView, savedInstance: true SomethingFragment{44b835a} (d5190920-63a8-4356-bf02-41936dd710a5) id=0x7f0901c8}
action
Fragment onCreateView, savedInstance: true SomethingFragment{44b835a} (d5190920-63a8-4356-bf02-41936dd710a5) id=0x7f0901c8}
Fragment onDestroy SomethingFragment{44b835a} (d5190920-63a8-4356-bf02-41936dd710a5) id=0x7f0901c8}
Activity onDestroy com.sen.osmo.ui.SomethingActivity@96035a6
Is this approach correct??
However, this is a deprecated method now and as I found we should use
requireActivity().supportFragmentManager
but this gives an exception of
java.lang.IllegalStateException: Cannot remove Fragment attached to a different FragmentManager.
So eventually what solution should we use? Is there a way to use the navigation controller to pop the fragment B so as to go back to fragment A without using navigate ?