Fixed
Status Update
Comments
ia...@gmail.com <ia...@gmail.com> #2
Another option is to:
1) Inflate the graph separately via navController.navInflater.inflate(R.navigation.graph)
2) Get a reference to your starting destination via graph.findNode(graph.startDestination)
3) Set its default arguments via destination.setDefaultArguments(bundleOf("id" to 1))
4) Set the now updated graph on the NavController via navController.graph = graph
Now your start destination will have your arguments.
1) Inflate the graph separately via navController.navInflater.inflate(R.navigation.graph)
2) Get a reference to your starting destination via graph.findNode(graph.startDestination)
3) Set its default arguments via destination.setDefaultArguments(bundleOf("id" to 1))
4) Set the now updated graph on the NavController via navController.graph = graph
Now your start destination will have your arguments.
il...@google.com <il...@google.com> #3
Re #2, yes that's an option (just be sure to *not* use the app:navGraph attribute on the NavHostFragment).
Another workaround is to directly access the Activity extras from your Fragment via YourFragmentArgs.fromBundle(requireActivity().intent.extras), but obviously that breaks the encapsulation of the Fragment.
I think overloads for NavHostFragment.create() and for setGraph() which take a Bundle of initial destination arguments would make this a lot easier.
Another workaround is to directly access the Activity extras from your Fragment via YourFragmentArgs.fromBundle(requireActivity().intent.extras), but obviously that breaks the encapsulation of the Fragment.
I think overloads for NavHostFragment.create() and for setGraph() which take a Bundle of initial destination arguments would make this a lot easier.
ma...@gmail.com <ma...@gmail.com> #4
I think I have a related issue. My scenario:
<navigation app:startDestination="@id/homeFragment">
<fragment android:id="@+id/homeFragment" />
<fragment android:id="@+id/loginFragment" />
<action
android:id="@+id/action_loginFragment_pop"
app:enterAnim="@anim/nav_default_enter_anim"
app:exitAnim="@anim/nav_default_exit_anim"
app:popEnterAnim="@anim/nav_default_pop_enter_anim"
app:popExitAnim="@anim/nav_default_pop_exit_anim"
app:popUpTo="@id/loginFragment"
app:popUpToInclusive="true" />
</fragment>
<action
android:id="@+id/action_global_loginFragment"
app:destination="@id/loginFragment"
app:enterAnim="@anim/nav_default_enter_anim"
app:exitAnim="@anim/nav_default_exit_anim"
app:popEnterAnim="@anim/nav_default_pop_enter_anim"
app:popExitAnim="@anim/nav_default_pop_exit_anim" />
</navigation>
--------------------
Activity:
override fun onCreate(savedInstanceState: Bundle?) {
....
if (isUserNotLoggedIn) {
navController.navigate(NavGraphMainDirections.actionGlobalLoginFragment())
}
}
--------------------
LoginFragment:
fun performLogin() {
...
view?.findNavController()?.navigate(R.id.action_loginFragment_pop)
}
--------------------
When popping the LoginFragment, the startDestination appears without any transition. I believe because the startDestination is hardcoded to navigate without either args nor NavOptions:
NavController:
private void onGraphCreated() {
...
// Navigate to the first destination in the graph
// if we haven't deep linked to a destination
mGraph.navigate(null, null);
}
In my case (assuming I didn't get anything wrong) it would be appropriate to have the chance to specifiy NavOptions as well as arguments.
<navigation app:startDestination="@id/homeFragment">
<fragment android:id="@+id/homeFragment" />
<fragment android:id="@+id/loginFragment" />
<action
android:id="@+id/action_loginFragment_pop"
app:enterAnim="@anim/nav_default_enter_anim"
app:exitAnim="@anim/nav_default_exit_anim"
app:popEnterAnim="@anim/nav_default_pop_enter_anim"
app:popExitAnim="@anim/nav_default_pop_exit_anim"
app:popUpTo="@id/loginFragment"
app:popUpToInclusive="true" />
</fragment>
<action
android:id="@+id/action_global_loginFragment"
app:destination="@id/loginFragment"
app:enterAnim="@anim/nav_default_enter_anim"
app:exitAnim="@anim/nav_default_exit_anim"
app:popEnterAnim="@anim/nav_default_pop_enter_anim"
app:popExitAnim="@anim/nav_default_pop_exit_anim" />
</navigation>
--------------------
Activity:
override fun onCreate(savedInstanceState: Bundle?) {
....
if (isUserNotLoggedIn) {
navController.navigate(NavGraphMainDirections.actionGlobalLoginFragment())
}
}
--------------------
LoginFragment:
fun performLogin() {
...
view?.findNavController()?.navigate(R.id.action_loginFragment_pop)
}
--------------------
When popping the LoginFragment, the startDestination appears without any transition. I believe because the startDestination is hardcoded to navigate without either args nor NavOptions:
NavController:
private void onGraphCreated() {
...
// Navigate to the first destination in the graph
// if we haven't deep linked to a destination
mGraph.navigate(null, null);
}
In my case (assuming I didn't get anything wrong) it would be appropriate to have the chance to specifiy NavOptions as well as arguments.
il...@google.com <il...@google.com>
ap...@google.com <ap...@google.com> #5
Project: platform/frameworks/support
Branch: androidx-master-dev
commit c66023fdc48fdadb09aa031710c592d4c81fe2b4
Author: Ian Lake <ilake@google.com>
Date: Mon Oct 01 14:35:33 2018
Allow passing arguments to the start destination
Make an explicit mechanism for passing a Bundle
of arguments to the start destination of the
navigation graph when calling setGraph() or
NavHostFragment.create().
It is still up to the developer to specifically
construct that Bundle. This is to prevent the
potential arbitrary Intent extras (which may
have been crafted maliciously) to enter the
Fragment arguments (which should be trusted).
Test: new tests in runtime and fragment
BUG: 110300470
Change-Id: I03a753ffc706e061483207788a3cc31dec890e6e
M navigation/fragment/src/androidTest/AndroidManifest.xml
A navigation/fragment/src/androidTest/java/androidx/navigation/fragment/StartDestinationArgsTest.kt
A navigation/fragment/src/androidTest/res/layout/start_destination_args_activity.xml
A navigation/fragment/src/androidTest/res/navigation/nav_fragment_start_args.xml
M navigation/fragment/src/main/java/androidx/navigation/fragment/NavHostFragment.java
M navigation/runtime/src/androidTest/java/androidx/navigation/NavControllerTest.kt
M navigation/runtime/src/main/java/androidx/navigation/NavController.java
https://android-review.googlesource.com/774471
https://goto.google.com/android-sha1/c66023fdc48fdadb09aa031710c592d4c81fe2b4
Branch: androidx-master-dev
commit c66023fdc48fdadb09aa031710c592d4c81fe2b4
Author: Ian Lake <ilake@google.com>
Date: Mon Oct 01 14:35:33 2018
Allow passing arguments to the start destination
Make an explicit mechanism for passing a Bundle
of arguments to the start destination of the
navigation graph when calling setGraph() or
NavHostFragment.create().
It is still up to the developer to specifically
construct that Bundle. This is to prevent the
potential arbitrary Intent extras (which may
have been crafted maliciously) to enter the
Fragment arguments (which should be trusted).
Test: new tests in runtime and fragment
BUG: 110300470
Change-Id: I03a753ffc706e061483207788a3cc31dec890e6e
M navigation/fragment/src/androidTest/AndroidManifest.xml
A navigation/fragment/src/androidTest/java/androidx/navigation/fragment/StartDestinationArgsTest.kt
A navigation/fragment/src/androidTest/res/layout/start_destination_args_activity.xml
A navigation/fragment/src/androidTest/res/navigation/nav_fragment_start_args.xml
M navigation/fragment/src/main/java/androidx/navigation/fragment/NavHostFragment.java
M navigation/runtime/src/androidTest/java/androidx/navigation/NavControllerTest.kt
M navigation/runtime/src/main/java/androidx/navigation/NavController.java
il...@google.com <il...@google.com> #6
Passing arguments to the start destination can now be done via
NavHostFragment.create(R.navigation.graph, args)
or
navController.setGraph(R.navigation.graph, args)
or
navController.setGraph(navGraph, args)
This will be available in alpha07
NavHostFragment.create(R.navigation.graph, args)
or
navController.setGraph(R.navigation.graph, args)
or
navController.setGraph(navGraph, args)
This will be available in alpha07
[Deleted User] <[Deleted User]> #7
Component used: Navigation graph
Version used: 1.0.0-rc02
Devices/Android versions reproduced on: Device running Android P, compiled in SDK 28
Marked as fixed.
1.declare NavHostFragment with id
2. Inflate the container
3. declare navGraph with id
4.Extract from Intent
5. val navArgument= NavArgument.Builder().setDefaultValue("Required Bundle").build()
6.Add argument with graph
val navHostFragment = container as NavHostFragment
val inflater = navHostFragment.navController.navInflater
val graph = inflater.inflate(R.navigation.wash_request)
var place : String = intent?.getStringExtra("place") as String
var latlong : String = intent?.getStringExtra("latlong") as String
var selectCar = CarWashDetail(place,latlong)
val navArgument= NavArgument.Builder().setDefaultValue(selectCar).build()
graph.addArgument("CarWashDetails",navArgument)
navHostFragment.navController.graph = graph
Version used: 1.0.0-rc02
Devices/Android versions reproduced on: Device running Android P, compiled in SDK 28
Marked as fixed.
1.declare NavHostFragment with id
2. Inflate the container
3. declare navGraph with id
4.Extract from Intent
5. val navArgument= NavArgument.Builder().setDefaultValue("Required Bundle").build()
6.Add argument with graph
val navHostFragment = container as NavHostFragment
val inflater = navHostFragment.navController.navInflater
val graph = inflater.inflate(R.navigation.wash_request)
var place : String = intent?.getStringExtra("place") as String
var latlong : String = intent?.getStringExtra("latlong") as String
var selectCar = CarWashDetail(place,latlong)
val navArgument= NavArgument.Builder().setDefaultValue(selectCar).build()
graph.addArgument("CarWashDetails",navArgument)
navHostFragment.navController.graph = graph
Description
Version used: 1.0.0-alpha01
Devices/Android versions reproduced on: Device running Android P, compiled in SDK 27
If this is a bug in the library, we would appreciate if you could attach:
- Sample project to trigger the issue.
- A screenrecord or screenshots showing the issue (if UI related).
In order to instantiate the view of my first fragment, some data needs to be passed from the current Activity to the primary fragment. Currently, I don't see a clear way to do this. In the same way one can navigate from fragment to fragment while passing arguments via the NavController's navigate method, it would be helpful if there was some method to pass a bundle to the first nav fragment and update the graph associated with the NavHostFragment before inflating the view.
Please do let me know if there is some way to do this that I'm missing. Currently I'm setting up a dummy fragment to start with that will manage passing the data to the intended first fragment.