Almost every app uses some kind of navigation, allows users to move from one screen to another. In this article, we will learn to implement Navigation in Jetpack Compose using Compose way. We will build a simple app demonstrating Jetpack compose navigation, It will have three screens(Home, Profile, and Settings). It will navigate to Settings Screen with some data and to Profile Screen without any data. A sample video is given below to get an idea about what we are going to do in this article.
Prerequisites:
- Basic Knowledge of Kotlin.
- Knowledge of Jetpack Compose.
Steps to Implement Navigation and Passing Data
Step 1 : Create a New Project
To create a new project in the Android Studio, please refer to How to Create a new Project in Android Studio with Jetpack Compose.
Note: Select Kotlin as the programming language.
Step 2 : Add dependencies
Open build.gradle(app) and add this line inside dependencies.
implementation("androidx.navigation:navigation-compose:2.8.8")Step 3 : Creating Routes
Create a file with the name Routes. Add the following code. It will contain the route names of all screens.
Routes.kt:
package com.geeksforgeeks.demo
sealed class Routes(val route: String) {
data object Home : Routes("home")
data object Profile : Routes("profile")
data object Settings : Routes("setting")
}
Step 4 : Working with the screens
It will have three screens, so we need to create three composable. Create a package with name screens and create three files (Home.kt, Profile.kt, Settings.kt).

package com.geeksforgeeks.demo.screens
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.*
import androidx.compose.ui.graphics.*
import androidx.compose.ui.unit.*
import androidx.navigation.NavHostController
import com.geeksforgeeks.demo.Routes
@Composable
fun Home(navController: NavHostController) {
// Basic counter to display on screen
var counter by remember {
mutableIntStateOf(0)
}
// Box to center Items
Box(
modifier = Modifier
.fillMaxSize()
.background(Color.White), contentAlignment = Alignment.Center
) {
Column {
// Text to show counter on Screen
Text(text = "Home, Counter is $counter", color = Color.Black)
Spacer(modifier = Modifier.height(20.dp))
// Button increases the counter
Button(onClick = { counter++ }) {
Text(text = "Increment Counter", color = Color.White)
}
Spacer(modifier = Modifier.height(20.dp))
// Navigate to Profile Screen
Button(onClick = {
navController.navigate(Routes.Profile.route)
}) {
Text(text = "Navigate to Profile", color = Color.White)
}
Spacer(modifier = Modifier.height(20.dp))
// Navigate to Settings Screen
Button(onClick = {
navController.navigate(Routes.Settings.route + "/$counter")
}) {
Text(text = "Navigate to Settings", color = Color.White)
}
}
}
}
package com.geeksforgeeks.demo.screens
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.*
import androidx.compose.ui.graphics.*
import androidx.compose.ui.unit.*
@Composable
fun Profile() {
Box(
modifier = Modifier
.fillMaxSize()
.background(Color.White), contentAlignment = Alignment.Center
) {
Column {
Text(
text = "Navigation without arguments",
Modifier.padding(10.dp),
color = Color.Black
)
Text(text = "Profile Screen", Modifier.padding(10.dp), color = Color.Black)
}
}
}
package com.geeksforgeeks.demo.screens
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.*
import androidx.compose.ui.graphics.*
import androidx.compose.ui.unit.*
@Composable
fun Setting(counter: String?) {
Box(
modifier = Modifier
.fillMaxSize()
.background(Color.White), contentAlignment = Alignment.Center
) {
Column {
Text(text = "Navigation with arguments", Modifier.padding(10.dp), color = Color.Black)
// Display the counter
Text(
text = "Settings Screen, passed data is $counter",
Modifier.padding(10.dp),
color = Color.Black
)
}
}
}
Step 5: Working with the MainActivity and Navigation Components
Create a function with the name ScreenMain in MainActivity.kt which will contain NavHost and the Composable for navigation. Refer to the comments in the code for better understanding. And finally, call this Composable from setContent in onCreate of MainActivity. Further, you can add animations when opening the screens using Compose Animation APIs.
MainActivity.kt:
package com.geeksforgeeks.demo
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.material3.Surface
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.Color
import androidx.navigation.compose.*
import com.geeksforgeeks.demo.screens.*
import com.geeksforgeeks.demo.ui.theme.DemoTheme
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
DemoTheme(dynamicColor = false, darkTheme = false) {
Surface(color = Color.White) {
ScreenMain()
}
}
}
}
}
@Composable
fun ScreenMain() {
val navController = rememberNavController()
NavHost(navController = navController, startDestination = Routes.Home.route) {
// Home
composable(Routes.Home.route) {
// pass the navController
Home(navController = navController)
}
// Profile
composable(Routes.Profile.route) {
Profile()
}
// Settings
// "/{id}" - its the argument passed down from homeScreen
composable(Routes.Settings.route + "/{id}") { navBackStack ->
// Extracting the argument
val counter = navBackStack.arguments?.getString("id")
Setting(counter = counter)
}
}
}