DEV Community

Maria Luíza
Maria Luíza

Posted on

Navigation With Compose

Hello, amazing person of the internet! Hope you’re doing well.

One crucial aspect of creating seamless and intuitive user experiences is effective navigation within an app.

That’s where the Navigation Component with Jetpack Compose comes into play.

 

Implementation

Let’s implement the navigation library in the build.gradle file (module):



dependencies {

    [...]

    val nav_version = "2.6.0"
    implementation("androidx.navigation:navigation-compose:$nav_version")
}


Enter fullscreen mode Exit fullscreen mode

 

Screens

Now, I am going to create two compose files to represent our screens:

Fist Screen:



@Composable
fun ScreenOne() {
    Column(
        modifier = Modifier.fillMaxSize(),
        horizontalAlignment = Alignment.CenterHorizontally,
        verticalArrangement = Arrangement.Center
    ) {
        Text(text = "Screen One")
        Button(
            onClick = { /*TODO*/ }
        ) {
            Text(text = "Next Screen")
        }
    }
}


Enter fullscreen mode Exit fullscreen mode

Screen Two:



@Composable
fun ScreenTwo() {
    Column(
        modifier = Modifier.fillMaxSize(),
        horizontalAlignment = Alignment.CenterHorizontally,
        verticalArrangement = Arrangement.Center
    ) {
        Text(text = "Screen Two")
        Button(
            onClick = { /*TODO*/ }
        ) {
            Text(text = "Next Screen")
        }
    }
}


Enter fullscreen mode Exit fullscreen mode

When working with the navigation component, you need to know certain names, such as NavController and NavHost.

 

NavController

You can think of the NavController as being responsible for maintaining the state of each screen.

You need to implement in the starting point of your app. To create the NavController just call rememberNavController() method.



class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            NavigationComponentTheme {
                Surface {
                    val navController = rememberNavController()
                }
            }
        }
    }
}


Enter fullscreen mode Exit fullscreen mode

 

NavHost

The NavHost connects the NavController to a navigation graph, which defines the composables you can navigate between.

Let’s create a file for our NavHost:



@Composable
fun CustomNavHost(
    navController: NavController
) {

}


Enter fullscreen mode Exit fullscreen mode

We need to pass the NavController as a parameter because we require it to control the screens.

Now let’s call the NavHost method:



@Composable
fun CustomNavHost(
    navController: NavHostController
) {
    NavHost(
        // the nav controller that we receive has parameter
        navController = ,
        // The screen your app should display first
        startDestination = 
    ) {

    }
}


Enter fullscreen mode Exit fullscreen mode

We need to call our screen files:



@Composable
fun CustomNavHost(
    navController: NavHostController
) {
    NavHost(
        navController = navController,
        startDestination = "SCREEN_ONE"
    ) {
        composable(route =  "SCREEN_ONE"){
            ScreenOne()
        }
        composable(route = "SCREEN_TWO") {
            ScreenTwo()
        }
    }
}


Enter fullscreen mode Exit fullscreen mode

You need to define a route to each screen.

Let’s go back to our MainActivity and set up our NavHost:



class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            NavigationComponentTheme {
                Surface {
                    val navController = rememberNavController()
                    CustomNavHost(navController = navController)
                }
            }
        }
    }
}


Enter fullscreen mode Exit fullscreen mode

To control the flow and navigate between screens, each screen needs to have access to the NavController.

In your NavHost file, pass the NavController as a parameter for your screens.



@Composable
fun CustomNavHost(
    navController: NavHostController
) {
    NavHost(
        navController = navController,
        startDestination = "SCREEN_ONE"
    ) {
        composable(route = "SCREEN_ONE") {
            ScreenOne(navController)
        }
        composable(route = "SCREEN_TWO") {
            ScreenTwo(navController)
        }
    }
}


Enter fullscreen mode Exit fullscreen mode

And add the parameter to each screen:

Fist Screen:



@Composable
fun ScreenOne(navController: NavHostController) {
[...]


Enter fullscreen mode Exit fullscreen mode

Screen Two:



@Composable
fun ScreenTwo(navController: NavHostController) {
[...]


Enter fullscreen mode Exit fullscreen mode

 

Navigate

To start “an activity”, You simply need to call it using the navController and provide the route of the screen you wish to navigate to:



navController.navigate(route = "SCREEN_TWO")


Enter fullscreen mode Exit fullscreen mode

I am going to call ScreenTwo on ScreenOne and call ScreenOne on ScreenTwo.

Image description

So, my final screen files will look like this:

Fist Screen:



@Composable
fun ScreenOne(navController: NavHostController) {
    Column(
        modifier = Modifier.fillMaxSize(),
        horizontalAlignment = Alignment.CenterHorizontally,
        verticalArrangement = Arrangement.Center
    ) {
        Text(text = "Screen One")
        Button(
            onClick = {
                navController.navigate(route = "SCREEN_TWO")
            }
        ) {
            Text(text = "Next Screen")
        }
    }
}


Enter fullscreen mode Exit fullscreen mode

Screen Two:



@Composable
fun ScreenTwo(navController: NavHostController) {
    Column(
        modifier = Modifier.fillMaxSize(),
        horizontalAlignment = Alignment.CenterHorizontally,
        verticalArrangement = Arrangement.Center
    ) {
        Text(text = "Screen Two")
        Button(
            onClick = {
                navController.navigate("SCREEN_ONE")
            }
        ) {
            Text(text = "Next Screen")
        }
    }
}


Enter fullscreen mode Exit fullscreen mode

 

Conclusion

You can also pass arguments, use nested navigation, combine it with bottom bar navigation, and it’s super easy to test.

The navigation component is one of the many features of Compose, allowing you to navigate between screens in a easy way.

Check here my article about navigation bar.

All the code and exemple it is on this repository.

Happy coding ❤

 

Please let me know what you think in the comments…

Connect with me 👇

Linkedin

GitHub

Top comments (1)

Collapse
 
alan_b_2583cdf898f4a581df profile image
Alan B

Thank you Maria! You got me past my sticking point!