Pass Arguments to Destinations : Jetpack Compose Navigation
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)
}
}
/* ... */
}
}
Passing 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 case, 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 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 Naivgation 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