Introduction:
In Jetpack Compose, you can navigate between different screens using the NavController
class from the Navigation component. Passing arguments to the Destination will be like adding Query param or Path to a URL.
To pass arguments to the destination screen, you need to add argument placeholders to the route.
For example, let’s say you have a screen called DetailScreen
that displays details of a user, and you want to pass the ID of the user as an argument when navigating to this screen. You can define the route for DetailScreen
as "detail/{uId}"
, where uId
is the placeholder for the ID of the user.
Receiving end:
@Composable
fun MyNavHost() {
val navController = rememberNavController()
NavHost(
navController = navController,
startDestination = "home"
) {
composable("detail/{uId}") { navBackStackEntry ->
/* Extracting the id from the route */
val uId = navBackStackEntry.arguments?.getString("uId")
/* We check if it's not null */
uId?.let { id->
DetailScreen(uId = id)
}
}
/* ... */
}
}
Receiving Object:
Remember, you can only pass a string value to your Destination. But, if you have a data class and want to pass it to your composable then a possible solution is to convert your object to a string using any convertor.
composable("detail/{user}") { navBackStackEntry ->
// Creating gson object
val gson: Gson = GsonBuilder().create()
/* Extracting the user object json from the route */
val userJson = navBackStackEntry.arguments?.getString("user")
// Convert json string to the User data class object
val userObject = gson.fromJson(userJson, User::class.java)
DetailScreen(user = userObject)
}
Multiple args:
If you want to pass multiple arguments then you can define a route with multiple placeholders separated by slashes (“/”). For example:
composable("detail/{name}/{id}") { backStackEntry ->
// Extracting the arguments from the route
val name= backStackEntry.arguments?.getString("name")
val id= backStackEntry.arguments?.getString("id")
// Check if arguments are not null and render the screen
if (name!= null && id!= null) {
DetailScreen(name, id)
}
}
Optional args:
If in some cases, you don’t want to have any argument. Then, you can also define it as an optional argument. But, to define an optional argument...
We have to use query parameter syntax (
"?argName={argName}"
)We must set a
defaultValue
, or havenullability = true.
composable(
route = "detail?uId={uId}",
arguments = listOf(
navArgument("uId") {
defaultValue = 0
type = NavType.IntType
}
)
) { navBackStackEntry ->
/* Extracting the id from the route */
val uId = navBackStackEntry.arguments?.getInt("uId")
/* We check if is null */
uId?.let {
DetailScreen(uId = it)
}
}
And if you want to add more arguments add & between arguments, "?argName1={argName1}&argName2={argName2}"
NOTE: Your passed string/JSON string value should not contain a “/” or your app will crash due to an unexpected path/route.
Sending end:
@Composable
fun HomeScreen(navController: NavController) {
Button(
onClick = {
/* Replacing {uId} with 1 */
navController.navigate(
"detail/{uId}" //Just modify your route accordingly
.replace(
oldValue = "{uId}",
newValue = "1"
)
)
}
) {
Text(text = "Navigate to Detail with id 1")
}
}
Passing Object:
@Composable
fun HomeScreen(navController: NavController) {
val userObj = User()
Button(
onClick = {
val gson: Gson = GsonBuilder().create()
val userJson = gson.toJson(userObj)
/* Replacing {user} with userJson */
navController.navigate(
"detail/{user}" //Just modify your route accordingly
.replace(
oldValue = "{user}",
newValue = userJson
)
)
}
) {
Text(text = "Navigate to Detail with userJson")
}
}
Conclusion:
This can look a little complex to pass args using Navigation in Jetpack compose, but once you know the basics you’re more ready to expand its usage. It’s no different than passing args to a URL.
I hope you found this helpful. If yes, then do FOLLOW ‘Sagar Malhotra’ for more Android-related content.
#androidWithSagar #android #androiddevelopment #development #compose #kotlin