Navigating with Jetpack Compose

Francisco J. Barrios
Jan 20 · 4 min read

The easiest way to implement Navigation and Jetpack Compose

Image for post
Image for post
source: “https://unsplash.com/@timgraf99

TL;DR version: Here is the GitHub repository https://github.com/franciscobarrios/NavCompose

What is this?

navigation in a Jetpack Compose application, what I have here is a single activity application with 4 views, with the idea of keeping it simple as possible.

Image for post
Image for post

This is the project structure:

Image for post
Image for post
  • nav: contains Navigation.kt this handle the navigation logic
  • ui: this is created by Android Studio and contains everything related to ui
  • view: contains views, maybe we can say those are like fragments?
  • MainActivity: is the only activity in the app
  • NavComposeApp: is a composable function

This is an “One Activity app” with four views

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

navComposeApp()

navComposeApp is a composable function to handle the UI, this function displays a view depending on the user’s navigation

@Composable
fun navComposeApp() {
val navController = rememberNavController()
val actions = remember(navController) { Action(navController) }
NavComposeTheme {
NavHost(
navController = navController,
startDestination = Home
)
{
composable(Home) {
home(action = actions.view1)
}
composable(View1) {
view1(action = actions.view2)
}
composable(View2) {
view2(action = actions.view3)
}
composable(View3) {
view3()
}
}
}
}

Is important to understand this: Action(navController)

object Destinations {
const val Home = "home"
const val View1 = "view1"
const val View2 = "view2"
const val View3 = "view3"
}

class Action(navController: NavHostController) {
val home: () -> Unit = { navController.navigate(Home) }
val view1: () -> Unit = { navController.navigate(View1) }
val view2: () -> Unit = { navController.navigate(View2) }
val view3: () -> Unit = { navController.navigate(View3) }
val navigateBack: () -> Unit = { navController.popBackStack() }
}

Action is class that use a NavHostController object, this is called in the navComposeApp function

val actions = remember(navController) { Action(navController) }

Then we have four views like this one:

@Composable
fun home(action: () -> Unit) {
common(
text = "this is Home",
action = action
)
}

Every view is a composable function and receive:

action: () -> Unit

Each view is a composable function and receives:

@Composable
fun common(
text: String,
action: () -> Unit
)

Common is another composable function, and receive a text and an action,

text: is just to show something in the view, when the user press fab this will navigate to the next view and text will change and show a different message,

action: decide which view the user will navigate

@Composable
fun common(
text: String,
action: () -> Unit
) {
Scaffold(
topBar = {
TopAppBar(
title = { Text(text = "TopAppBar") },
backgroundColor = purple500,
navigationIcon = {
IconButton(onClick = action) {
Icon(asset = Icons.Filled.ArrowBack)
}
}
)
},
bodyContent = {
showText(text = text)
},
isFloatingActionButtonDocked = true,
floatingActionButtonPosition = FabPosition.Center,
floatingActionButton = {
FloatingActionButton(
onClick = action,
icon = {
Icon(asset = Icons.Default.Add)
}
)
},
bottomBar = {
BottomAppBar(
backgroundColor = purple500,
cutoutShape = CircleShape
) {

}
}
)
}

@Composable
fun showText(text: String) {
Box(Modifier.fillMaxSize()) {
Text(
text = text,
fontSize = 32.sp,
modifier = Modifier
.align(Alignment.Center)
.padding(
start = 36.dp,
end = 36.dp
)
)
}
}

As I said before, common will receive a text and a action and will create a Scaffold with: topBar, bodyContent, fab and bottomBar, in the fab we will use the action

floatingActionButton = {
FloatingActionButton(
onClick = action,
icon = {
Icon(asset = Icons.Default.Add)
}
)
}

So every time the user presses the FAB they will navigate to the next view

Then again in navComposeApp

NavComposeTheme {
NavHost(
navController = navController,
startDestination = Home
) {
composable(Home) { home(action = actions.view1) }
composable(View1) { view1(action = actions.view2) }
composable(View2) { view2(action = actions.view3) }
composable(View3) { view3() }
}
}

We define that: when the user is in Home and presses fab, the user will navigate to View1 and so on … until he reaches View3

So that’s it

The Startup

Medium's largest active publication, followed by +773K people. Follow to join our community.

Francisco J. Barrios

Written by

Android developer (code + music) = happiness (https://franciscobarrios.github.io)

The Startup

Medium's largest active publication, followed by +773K people. Follow to join our community.

Francisco J. Barrios

Written by

Android developer (code + music) = happiness (https://franciscobarrios.github.io)

The Startup

Medium's largest active publication, followed by +773K people. Follow to join our community.

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store