A Beginner’s Guide to Jetpack Compose Navigation

Onur Uğur
3 min readMay 5, 2024

Hey folks! Let’s dive into Jetpack Compose’s navigation system to build smooth and intuitive user flows. With Compose, navigation is more explicit than before, making the flow easier to manage. Here’s a quick guide to creating a basic setup.

First Things First: Dependencies

To start, include the Navigation Compose dependency in your build.gradle (Module) file:

implementation ("androidx.navigation:navigation-compose:2.5.1")

This implementation can be changed due to your gradle version

Creating Screens

We’ll create a Home screen that leads to a Profile screen. Each screen is a simple composable function:

@Composable
fun HomeScreen(navigateToProfile: () -> Unit) {
Column(
modifier = Modifier.fillMaxSize(),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
Button(onClick = { navigateToProfile() }) {
Text("Go to Profile")
}
}
}

@Composable
fun ProfileScreen(navigateBack: () -> Unit) {
Column(
modifier = Modifier.fillMaxSize(),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
Text("Welcome to the Profile Screen")
Spacer(modifier = Modifier.height(16.dp))
Button(onClick = { navigateBack() }) {
Text("Back to Home")
}
}
}

Remember this is just for example normally these screen definitions are not the best practice

Setting Up Navigation

Now, let’s set up our navigation graph using NavController and NavHost. Here's the code:

@Composable
fun AppNavigation() {
val navController = rememberNavController()

NavHost(navController = navController, startDestination = "home") {
composable("home") {
HomeScreen(navigateToProfile = { navController.navigate("profile") })
}
composable("profile") {
ProfileScreen(navigateBack = { navController.popBackStack() })
}
}
}

What’s happening here:

1)NavController Setup:

  • val navController = rememberNavController():
  • Creates and remembers a NavController instance.
  • NavController is an object that manages the app's navigation stack.
  • The rememberNavController function creates a persistent instance that will survive recompositions and configuration changes.

2) NavHost Composable:

  • NavHost(navController = navController, startDestination = "home"):
  • The NavHost composable is the container where navigation destinations are defined and displayed.
  • Takes the NavController object as an argument to manage navigation actions.
  • The startDestination parameter specifies which screen is shown first when the app starts. Here, it's set to "home".

3) Navigation Graph:

  • Inside the NavHost block, two destinations are declared using the composable function. Each represents a screen in the app:

Home Screen:

  • composable("home"): Defines a destination with the route name "home".
  • Inside this block, the HomeScreen composable is called.
  • It accepts a navigateToProfile lambda that calls navController.navigate("profile") to switch to the "profile" route.

Profile Screen:

  • composable("profile"): Defines a destination with the route name "profile".
  • Inside this block, the ProfileScreen composable is invoked.
  • It accepts a navigateBack lambda that calls navController.popBackStack() to return to the previous screen (the Home screen in this case).

Putting It All Together

In your MainActivity, set the content to the navigation graph:

class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
AppNavigation()
}
}
}

Wrapping Up

With just a few lines, we’ve built a simple navigation system in Jetpack Compose. The NavController takes care of the back stack for you, making transitions seamless and smooth. Keep experimenting and adding more screens to build intuitive app flows.

--

--

Onur Uğur

Unlock your potential with productivity and passive income tips. Discover the power of Notion and AI tools achieve financial freedom. Let's thrive together!