Open Motazlubbad opened 5 years ago
Having the same issue. Any solution?
always!! i was also facing that problem. I hope this can help you. check the current destination id like for example if (findNavController().currentDestination?.id == R.id.currentfragmentname) { findNavController().navigate(R.id.action_currentfragmentname_to_anyfragmentname) }
+1 I'm having this problem too with jetpack navigation v.2.1.0
@DJDrama can you share the complete snippet of it?
Just use nested navigation.
Put the fragment in different navigation file and add it as nested navigation in other file.
You Just have set destination id same as your fragment id.
Like below
<fragment
android:id="@+id/externalProfileFragment"
android:name="com.social.footprint.ui.external_user_profile.ExternalProfileFragment"
android:label="ExternalProfileFragment"
tools:layout="@layout/external_profile_fragment">
<argument
android:name="user_id"
app:argType="string" />
<action
android:id="@+id/action_externalProfileFragment_to_externalProfileFragment"
app:destination="@id/externalProfileFragment" />
</fragment>
I want to do the same but I think this is not possible:
The nested graph encapsulates its destinations. As with a root graph, a nested graph must have a destination identified as the start destination. Destinations outside of the nested graph, such as those on the root graph, access the nested graph only through its start destination.
Taken from: Nested Navigation Graphs
So basically you can only have an action that will navigate to the "start destination" of a nested graph. No way to access an inner fragment/destination inside a nested graph. I think the solution is NOT to use nested graphs whenever you want to "share" a fragment/destination across multiple graphs.
UPDATE: I had to split the "nested graph" that contained the fragment that I wanted to share. Meaning that the fragment is now available to be used as a destination from other graphs. I think this is the correct solution. This forces you to think about your app flow and how you design your navigation graphs.
Take a look at: Nested Graphs
The main idea is that nested graphs should aim to represent an "independent" or "self-contained" flow of your app. If you need to "share" one of your fragments in one graph with other graphs, then there may be something wrong with your design. In my case it made me realize that the nested graph that contained my shared fragment was not necessary and didn't actually represent an independent flow of the app, it was better embedded in the main flow, which was the other graph that wanted to have access to the shared fragment. The good thing about using graphs is that it forces you to consider all these flows details, which can eventually help you to build better UI/navigation experience for the user.
I have even tried to create a nested graph per destination (means that graphs will contain only one single fragment which allows me to avoid the problem mentioned by @marcelo-s) and include them into a different graphs. Unfortunately in that case SafeArgs
plugin does not work properly and auto-generated FragmentDirections
does not contain actions
and arguments
.
I have even tried to create a nested graph per destination (means that graphs will contain only one single fragment which allows me to avoid the problem mentioned by @marcelo-s) and include them into a different graphs. Unfortunately in that case
SafeArgs
plugin does not work properly and auto-generatedFragmentDirections
does not containactions
andarguments
.
Well if you have 1 to 1 relationship between graphs and fragments, then there is no point in having "multiple graphs". In that case you can put all of the Fragments in one graph, that way you will for sure have access to any fragment you want.
I also had the issue of the Fragment Directions not being generated. Make sure you can build your app and build it, meaning you shouldn't have any errors on your project, that way gradle/maven can compile and generate the Classes with the actions.
@marcelo-s It's not about 1 to 1 relationship between graphs. The idea was to create a nested subgraph (with single destination-fragment
inside) for every fragment
which is going to be injected into multiple graphs. Then instead of every time directly registering a corresponding destination
as a <fragment id=...
we can include it like <include app:graph="@navigation/subgraph" />
. The advantage of this approach would be that you will have a single file (entry-point) for each shared fragment(between multiple graphs) and everywhere instead of registering the same fragment again and again (with exactly same actions
and arguments
) you could just include it as a subgraph
. Unfortunately this approach does not work because in case of <include app:graph="@navigation/subgraph" />
when SafeArgs
plugin generates FragmentDirections
it does not contain actions
and arguments
.
Unfortunately this approach does not work because in case of
when SafeArgs plugin generates FragmentDirections it does not contain actions and arguments.
Workaround:
Add an action with the same id to both root graph and subgraph (ex showSome
). Add arguments to SubgraphFragment
, then navigate from SomeRootFragment
via SubgraphFragmentDirections.showSome(args)
instead of SomeRootFragmentDirections.showSome()
.
You can create a CustomNavDirections data class and create your own NavDirections
data class CustomNavDirections( override val actionId: Int, override val arguments: Bundle ) : NavDirections
And then you can create an extension function with the argument you need and bundle can be obtained via the safe arguments
fun HomeFragmentDirections.Companion.actionHomeFragmentToTaskDetailNavGraph( taskId: Int ): NavDirections = CustomNavDirections( actionId = R.id.action_homeFragment_to_task_detail_nav_graph, arguments = TaskDetailFragmentArgs(taskId = taskId).toBundle() )
Use:
findNavController().navigate( directions = HomeFragmentDirections.actionHomeFragmentToTaskDetailNavGraph( taskId = taskId ) )
I think using global navigation action will solve this issue you can use it like below
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/navigation"
app:startDestination="@id/homeFragment">
<fragment
android:id="@+id/fragment1"
android:name="fragment1"
android:label="fragment 1">
<argument
android:name="id"
app:argType="integer" />
</fragment>
<action android:id="@+id/action_global_navigate_to_fragment1" app:destination="@id/fragment1"/>
</navigation>
and in you Kotlin class you can find the global action that you added in all you fragments with this navigation
I would like to navigate to fragment A in more than one graph.
"Now I get this error : navigation destination action_compareListFragment_to_productPageFragment is unknown to this NavController"
How should I handle this situation?