1

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 ?

thahgr
  • 718
  • 1
  • 10
  • 27
  • actually no, should we ? The app is not navigated using the graph, only the operations regarding one specific activity and those two fragments – thahgr Sep 06 '21 at 12:33
  • @memres could you please remove the name of the graph **_graph from your comment? Its my mistake to include the name on the question, i have edited it. – thahgr Sep 06 '21 at 12:35
  • added it to manifest, nothing changed – thahgr Sep 06 '21 at 12:57
  • 1
    I removed my first comment. Was not able to edit. No, you should not have nav_graph in both manifest and code. I had a similar problem with two instances of a fragment. The reason was, I had the nav graph twice. Once in AndroidManifest and once in code like you. Removing NavGraph from AndroidManifest solved my issue. But i think there is another problem in your case. – memres Sep 06 '21 at 13:54
  • thank you for the comments, unfortunately it seems to be another problem – thahgr Sep 07 '21 at 06:12

1 Answers1

0

I finally found the answer, instead of navigating back to the fragment you want, you need to pop them from the backstack. This doesnt create new instances and the lifecycle is correct.

            findNavController().popBackStack(R.id.nav_something_fragment, false)

Finally also saw this answer which says the same

thahgr
  • 718
  • 1
  • 10
  • 27