Easy Jetpack Compose Navigation Instance

That is a part of the Jetpack Compose navigation sequence:

I created this easy app to check out the navigation element in Jetpack Compose. That is how the app appears like.


These are the steps to implement this easy app.

1. Add Navigation Compose Library

In appbuild.gradle, add this dependency.

dependencies { 
    implementation "androidx.navigation:navigation-compose:2.5.0-alpha01" 

2. Create NavHostController

NavHostController is required to construct the navigation graph within the subsequent step which is used to navigate to completely different screens.

Create this NavHostController utilizing rememberNavController() in your root composable perform and go that into the NavGraph() composable perform.

non-public enjoyable MainScreen() { 
    SimpleNavComposeAppTheme { 
        val navController = rememberNavController() NavGraph(navController) 

3. Construct Navigation Graph

The navigation graph appears like this:

Login display is the beginning vacation spot. House display takes no navigation argument. Profile display takes 2 navigation arguments and search display takes 1 navigation argument.

To construct the navigation graph, you employ NavHost() composable perform and NavGraphBuilder.composable() perform to construct every composable display.

enjoyable NavGraph(navController: NavHostController) {
        navController = navController,
        startDestination = "login"
    ) {
        composable(route = "login") {

        composable(route = "dwelling") {

To navigate to dwelling display:


To pop again present stack:


To pop as much as login display:

navController.popBackStack(NavRoute.Login.path, inclusive = false)

Navigation With Arguments

navGraphBuilder.composable has 2 parameters – route and arguments. To navigation with argument, we wish to replace each route and arguments parameters.

That is route format for profile display. id is the primary parameter. showDetails is the second parameter.

route = "profile/{id}/{showDetails}"

The arguments parameter appears like this:

arguments = listOf( 
    navArgument("id") { kind = NavType.IntType }, 
    navArgument("showDetails") { kind = NavType.BoolType } 

You’ll be able to specify the NavType of the parameter. You can even set the defaultValue to make the argument non-obligatory.

    navArgument("showDetails") {
        kind = NavType.BoolType
        defaultValue = false

I personally will keep away from utilizing defautValue as a result of it requires your path to observe sure format (i.e. "profile/{id}/?showDetails={showDetails}"). ?showDetails is the non-obligatory arguement to permit you specify the defaultValue.

To retrieve the argument worth, you employ the NavBackStackEntry.arguments:

composable( ... ) { navBackStackEntry ->

    val args = navBackStackEntry.arguments

    val id = args?.getInt("id")!!

    showDetails = args?.getBoolean("showDetails")!!


That is an instance to navigate to profile display.

val id = 7 val showDetails = true navController.navigate("profile/$id/$showDetails")

Any Route Format Is Wonderful!

As a substitute of utilizing this (which I want as a result of it’s the easiest kind):

route = "profile/{id}/{showDetails}"

You need to use this (required in order for you showDetails to be non-obligatory):

route = "profile/{id}/?showDetails={showDetails}"

Or this (required in order for you each id and showDetails to be non-obligatory):

route = "profile/?id={id}/?showDetails={showDetails}"

However please do NOT use this:

route = "profile/{id}{showDetails}"

Please be sure to not less than put a separator (any string) between the navigation parameters. This navigation parameters might be parsed wrongly particularly they’re identical information kind.

In case you change the route format, you want to replace the navigation name too. For instance:

val id = 7 val showDetails = true 

Too A lot Boilerplate Code

You will have observed, the hard-coded strings are in all places. One mistake can simply crash the app. It’s liable to errors.

So what I did is to create this NavRoute class that has all of the hard-coded strings there. I additionally embody a utility features (i.e. withArgs() to construct the navigation path and withArgsFormat() to construct the route format string.

sealed class NavRoute(val path: String) {

    object Login: NavRoute("login")

    object House: NavRoute("dwelling")

    object Profile: NavRoute("profile") {
        val id = "id"
        val showDetails = "showDetails"

    object Search: NavRoute("search") {
        val question = "question"

    enjoyable withArgs(vararg args: String): String {
        return buildString {
            args.forEach{ arg ->

    enjoyable withArgsFormat(vararg args: String) : String {
        return buildString {
            args.forEach{ arg ->

Some utilization examples:



route = NavRoute.Search.withArgsFormat(NavRoute.Search.question)

Ultimate Ideas

I am undecided my NavRoute strategy above is the great one. I am additionally undecided if it makes the code unreadable? Possibly a bit? Nevertheless, it not less than can eliminate many hard-coded strings and no extra boilerplate code.

There’s a Compose Locations library which removes much more boilerplate code. I feel it’s higher to grasp the basic first earlier than attempting out this library.

Listed here are the steps to transform this app to make use of this library:

Supply Code

GitHub Repository: Demo_SimpleNavigationCompose

Related Articles


Please enter your comment!
Please enter your name here

Latest Articles