Jetpack Compose Navigation with custom Object

Georgios Metaxakis
2 min readMay 30, 2022

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 aJsonNavType and mark it as String, but it will be much cleaner in our Graph to have it marked as JsonNavType

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.

--

--