Jetpack Compose Navigation with custom Object
Jetpack Compose is Android’s modern toolkit for building native UI. It simplifies and accelerates UI development on Android. It helps to bring your app to life with less code and much faster. It also provides powerful tools, and intuitive Kotlin APIs that improve the developing experience.
In this article I will show you how to setup and use navigation with Compose and how to pass any custom object as argument to your composable screens.
To Navigate between those new UI elements we will use navigation-compose
library: Navigating with Compose
Using Navigation with Compose
Setup
To setup the library we need to add the library dependency on our app’s module build.gradle.kts
dependencies {
def nav_version = "2.4.2"
implementation("androidx.navigation:navigation-compose:$nav_version")
}
Getting started
We will define a navController variable that will be used as a parameter in our NavHost
val navController = rememberNavController()
Creating a NavHost
Each NavController
must be associated with a single NavHost
composable. The NavHost
links the NavController
with a navigation graph which specifies the composable destinations that you are able to navigate to. As you navigate between different composables, the content of the NavHost
is automatically recomposed. Each composable destination in our navigation graph is associated with a route.
Navigate to a composable
To navigate to a composable destination in the navigation graph, we must use the navigate()
method. The navigate()
method takes a single String
parameter that represents the destination’s route. To navigate from a composable within the navigation graph, call navigate()
. To do so we call the navigate()
method like below:
@Composable
fun Profile(navController: NavController) {
/*...*/
Button(onClick = { navController.navigate("friendslist") }) {
Text(text = "Navigate next")
}
/*...*/
}
Navigate with arguments
Navigation compose also supports passing arguments between composable destinations. We just need to add argument placeholders to our route, similar to how we add arguments to a deep link when using the base navigation library:
NavHost(startDestination = "profile/{userId}") {
...
composable(
"profile/{userId}",
arguments = listOf(navArgument("userId") { type = NavType.StringType })
) {...}
}
This works when we want to pass a simple argument type but will it work for a more complicated custom object like the Profile
data class below?
data class Profile (val firstName:String, val lastName:String)
No, in that case we have to use a Custom NavType
Using Custom NavType
Disclaimer: We can go without a
JsonNavType
and mark it asString
, but it will be much cleaner in ourGraph
to have it marked asJsonNavType
We will create a custom NavType that serialises to json the Profile
data class and pass it as aString
NavType. We need to define the following abstract class
that we will use for our Profile
data class
Now that we have defined how to expect the argument our Navigation component, we are able to navigate to any profile route with the following code:
That was it. I hope you found this article useful and you now understand how to pass custom objects as arguments to your composable screens easier.