I have an activity which has a NavHostFragment
. The activity receives certain values in its intent. I want to pass this data to the first fragment i.e startDestination
of the navigation graph. I couldn't find any documentation regarding this.
I have already gone through this question on SO but I can't seem to find the addDefaultArguments
method for navController.getGraph()
.
Is it possible to pass bundle to startDestination
?
i also came across same issue,
This is how i resolved it:
- Remove the the xml setup of NavHostFragment from
your_activity.xml
: i.e remove app:navGraph="@navigation/nav_graph
This is how your XML Should look like.
<fragment
android:id="@+id/nav_host"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
/>
Add Setup for NavHostFragment Programatically in onCreate()
of activity.
And pass bundle data using NavGraph.addDefaultArguments(bundleData)
api
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.editor_layout)
setupNavigation()
}
private fun setupNavigation() {
val navHostFragment = nav_host as NavHostFragment
val navController = navHostFragment.navController
val navInflater = navController.navInflater
val graph = navInflater.inflate(R.navigation.nav_graph)
graph.addDefaultArguments(intent!!.extras!!) // This is where you pass the bundle data from Activity to StartDestination
navHostFragment.navController.graph = graph
}
UPDATE:
Dependencies in my Project Gradle file:
dependencies {
def nav_version = "1.0.0-alpha08"
implementation "android.arch.navigation:navigation-fragment:$nav_version" // use -ktx for Kotlin
implementation "android.arch.navigation:navigation-ui:$nav_version" // use -ktx for Kotlin}
}
NOTE: In Navigation Component version 1.0.0-alpha09
for some reason google have no method as addDefaultArguments()
might be fixed soon. But lower version's have addDefaultArguments()
method.I have checked both in java and kotlin so try using 1.0.0-alpha07
or 1.0.0-alpha08
you can add arguments in your graph like this
<fragment
android:id="@+id/exampleFragment"
android:label="example_fragment"
android:name="com.example.yourapp.ui.ExampleFragment"
tools:layout="@layout/example_fragment">
<argument
android:name="exampleArgs"
app:argType="reference"
android:defaultValue="@string/example"/>
</fragment>
https://developer.android.com/guide/navigation/navigation-pass-data
I cannot find this method, too. It is not existant in the architecture components documentation.
But the is another way to set arguments to the start destination:
// Kotlin Code, in Fragment
with(findNavController().graph) {
get(startDestination).addArgument(...)
}
I checked the source code an saw that there a lot of changes regarding navigation destination and arguments.
I think the proper way to pass arguments to start destination is using 'addArgument' method, something like this:
val argument1 = 1 //First value
val argument2 = "Value" //Second value
val navArgument1=NavArgument.Builder().setDefaultValue(argument1).build()
val navArgument2=NavArgument.Builder().setDefaultValue(argument2).build()
navController.getGraph().addArgument("Key1",navArgument1)
navController.getGraph().addArgument("Key2",navArgument2)
Maybe there is a better way, but i didn't found one.
class MainActivity : BaseActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val navHostFragment = container as NavHostFragment
val inflater = navHostFragment.navController.navInflater
val graph = inflater.inflate(R.navigation.main_nav)
var data : Data = intent.getParcelableExtra("DATA") as Data
var bundle : Bundle = Bundle()
bundle.putParcelable("DATA", data)
graph.addDefaultArguments(bundle)
graph.addDefaultArguments(intent!!.extras!!)
navHostFragment.navController.graph = graph
}
}
Add the above code in Activity for sending the data using using navigation
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
var data = NavHostFragment.findNavController(this).graph.defaultArguments.getParcelable("DATA") as Booking
}
Add the above code in fragment side