package com.example.jetpackcompose.navigation import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.width import androidx.compose.material.Button import androidx.compose.material.Icon import androidx.compose.material.IconButton import androidx.compose.material.MaterialTheme import androidx.compose.material.Scaffold import androidx.compose.material.Text import androidx.compose.material.TopAppBar import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.ArrowBack import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp import androidx.navigation.NavHostController import androidx.navigation.compose.NavHost import androidx.navigation.compose.composable import androidx.navigation.compose.currentBackStackEntryAsState import androidx.navigation.compose.rememberNavController class ComposeNavigationActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { App() } } } @Composable fun App( navController: NavHostController = rememberNavController() ) { val backStackEntry by navController.currentBackStackEntryAsState() val currentScreen = AppScreen.valueOf( backStackEntry?.destination?.route ?: AppScreen.ScreenA.name ) Scaffold( topBar = { MyTopAppBar( currentScreen = currentScreen, canNavigateBack = navController.previousBackStackEntry != null, navigateUp = { navController.navigateUp() } ) } ) { innerPadding -> Column( modifier = Modifier.padding(innerPadding) // #1 ) { // or you can directly pass the modifier(#1) to AppNavHost(..) AppNavHost(navController) } } } @Composable private fun MyTopAppBar( currentScreen: AppScreen, canNavigateBack: Boolean, navigateUp: () -> Unit, modifier: Modifier = Modifier, ) { TopAppBar( title = { Text(text = currentScreen.title) }, modifier = modifier, navigationIcon = if (canNavigateBack) { { IconButton(onClick = navigateUp) { Icon( imageVector = Icons.Default.ArrowBack, contentDescription = "Back" ) } } } else null, ) } @Composable private fun AppNavHost( navController: NavHostController, ) { NavHost( navController = navController, startDestination = AppScreen.ScreenA.name, ) { composable(route = AppScreen.ScreenA.name) { ScreenA( onNextClick = { navController.navigate(AppScreen.ScreenB.name) } ) } composable(route = AppScreen.ScreenB.name) { ScreenB( onBackClick = { navController.navigateUp() }, onNextClick = { navController.navigate(AppScreen.ScreenC.name) }, ) } composable(route = AppScreen.ScreenC.name) { ScreenC( onBackClick = { navController.navigateUp() }, onResetClick = { navController.popBackStack( route = AppScreen.ScreenA.name, inclusive = false ) } ) } } } @Composable private fun ScreenA( onNextClick: () -> Unit, ) { Column( verticalArrangement = Arrangement.Center, horizontalAlignment = Alignment.CenterHorizontally, modifier = Modifier .fillMaxSize() .padding(16.dp) ) { Text( text = "Screen A", style = MaterialTheme.typography.h5 ) Spacer(modifier = Modifier.height(16.dp)) Button( onClick = onNextClick, modifier = Modifier.fillMaxWidth(), ) { Text(text = "Navigate to Screen B") } } } @Composable private fun ScreenB( onBackClick: () -> Unit, onNextClick: () -> Unit, ) { Column( verticalArrangement = Arrangement.Center, horizontalAlignment = Alignment.CenterHorizontally, modifier = Modifier .fillMaxSize() .padding(16.dp) ) { Text( text = "Screen B", style = MaterialTheme.typography.h5 ) Spacer(modifier = Modifier.height(16.dp)) Button( onClick = onBackClick, modifier = Modifier.fillMaxWidth() ) { Text(text = "Navigate to Screen A") } Spacer(modifier = Modifier.height(8.dp)) Button( onClick = onNextClick, modifier = Modifier.fillMaxWidth() ) { Text(text = "Navigate to Screen C") } } } @Composable private fun ScreenC( onBackClick: () -> Unit, onResetClick: () -> Unit, ) { Column( verticalArrangement = Arrangement.Center, horizontalAlignment = Alignment.CenterHorizontally, modifier = Modifier .fillMaxSize() .padding(16.dp) ) { Text( text = "Screen C", style = MaterialTheme.typography.h5 ) Spacer(modifier = Modifier.height(16.dp)) Button( onClick = onBackClick, modifier = Modifier.fillMaxWidth() ) { Text(text = "Navigate to Screen B") } Spacer(modifier = Modifier.width(8.dp)) Button( onClick = onResetClick, modifier = Modifier.fillMaxWidth() ) { Text(text = "Navigate to Screen A (PopupTo with Inclusive)") } } }