21

I have two graphs, so the first graph move from one fragment to an activity passing safeArgs to the activity.

val action = MyFragmentDirections.actionMyActivity(arg1, arg2)
Navigation.findNavController(view).navigate(action)  

Now in the second, I want to pass these arguments from MyActivity to a fragment which belongs to this activity.

I can get the args:

val args = MyActivity.fromBundle(intent.extras)

The problem is there is not a Directions file for this activity, so I can't pass the arguments.

JavierSegoviaCordoba
  • 6,531
  • 9
  • 37
  • 51
  • Are you trying to pass the arguments to the `startDestination` of your second activity's navigation graph? – ianhanniballake Dec 11 '18 at 20:26
  • The fragment from the MainActivity navigate to a DetailActivity which has a fragment (this is the home fragment, or startDestination of the DetailActivity graph). Can you check my answer to know if it is the correct way to solve it? – JavierSegoviaCordoba Dec 11 '18 at 20:52

3 Answers3

29

Navigation 1.0.0-alpha07 fixed the feature request for passing arguments to the start destination of a graph.

To use this, you'd need to:

  1. Remove the app:navGraph attribute from your NavHostFragment
  2. Call findNavController(R.id.your_nav_host_fragment).setGraph(R.navigation.your_graph, intent.extras)

Using the R.id of your NavHostFragment and R.navigation that you previously had on your app:navGraph tag. By passing the arguments into the setGraph call, your starting destination will get the arguments directly, without calling navigate again (which would, by default, create a new instance of the destination on your back stack - not what you want).

ianhanniballake
  • 191,609
  • 30
  • 470
  • 443
  • findNavController() is asking me for a view, I used findViewById. Can you edit it to findNavController(findViewById(R.id.your_nav_host_fragment)) please? Thank you for your help! – JavierSegoviaCordoba Dec 12 '18 at 00:09
  • Sounds like you aren't using the `-ktx` dependencies (you really, really should if you're doing Kotlin code). The correct replacement if you aren't using the Kotlin extensions is `Navigation.findNavController(this, R.id.your_nav_host_fragment)` – ianhanniballake Dec 12 '18 at 00:21
  • @Ian The asker mentioned that he passes data to the second activity via Safe Args. If the second activity is in a separate module (that doesn't depend on the first module), is it still possible to use Safe Args? I'm seeing that the generated Args class is created in the first module, so the second activity doesn't have access to it. Thanks! –  Jun 16 '19 at 09:30
  • Woah, nvm. I spoke too soon. I can just grab the extras from the intent.. awesome! –  Jun 16 '19 at 15:55
  • Any way to use SafeArgs with this? – m0skit0 Oct 09 '19 at 20:41
  • setGraph didn't work for us because on re-attach of container fragment (MyActivity in example), the destination fragment is always recreated, instead of re-attached. Solution: navHostFragment.arguments = requireArguments(); and in destination fragment: arguments = requireParentFragment().requireArguments() – Sebas LG Jun 07 '20 at 18:18
  • @ianhanniballake I am using nav version 2.3.5, and I am facing the same issue. Is there any more efficient way to achieve this? – Sweta Jain May 31 '21 at 12:53
  • I get an 'Activity does not have a NavController set on' error when trying to use `setGraph()`. – Chucky Jan 09 '22 at 16:20
  • FindNavController doesn't seem to work. You need to use this code to get the navcontroller to call setGraph on: `val navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment val navController = navHostFragment.navController` Source: https://stackoverflow.com/a/60597670/812013 – Chucky Jan 09 '22 at 16:41
9

I don't know if this is recommended, but it is working:

val args = MyActivity.fromBundle(intent.extras)
navController.navigate(R.id.myActivityFragment, args.toBundle())
JavierSegoviaCordoba
  • 6,531
  • 9
  • 37
  • 51
  • Using fragment's args: `val bundle = bundleOf("message_tip" to "") findNavController().navigate(R.id.helpFragment, HelpFragmentArgs.fromBundle(bundle).toBundle())` – jnfran92 Apr 09 '21 at 15:53
0

It work for me

  1. Remove the app:navGraph attribute from your NavHostFragment

        <androidx.fragment.app.FragmentContainerView
        android:id="@+id/video_view_fragment"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fillViewport="false"
        app:defaultNavHost="true"
        app:layout_constraintTop_toTopOf="parent"
         />
    
  2. and call

        navHostFragment = supportFragmentManager
        .findFragmentById(R.id.video_view_fragment) as NavHostFragment
    
    navHostFragment.navController.setGraph(R.navigation.video_navigation, intent.extras)
    
LamLT
  • 1
  • 2