I am currently using a navigation drawer in jetpack compose, but I have encountered a problem. When I added the navigation drawer to the mainDrawerScreen, it was displaying for every screen I added, in my case it said "Main Menu" for every screen composable when navigated to. This is not ideal.
I decided to remove TopAppBar from mainDrawerScreen and create a seperat scaffold with the TopAppBar for each composable screen. However, now the navigation does not work. I tried to create a trailing lambda for navigation but might have done it the wrong way. Anyone got a suggestion to why it is not opening the navDrawer? Appreciate the feedback!
MainDrawerSCreen:
@SuppressLint("UnusedMaterialScaffoldPaddingParameter")
@Composable
fun MainDrawerScreen() {
val scaffoldState = rememberScaffoldState(rememberDrawerState(DrawerValue.Closed))
val scope = rememberCoroutineScope()
val navController = rememberNavController()
Scaffold(
scaffoldState = scaffoldState,
drawerContent = {
DrawerHeader()
DrawerLayout(scope = scope, scaffoldState = scaffoldState , navController = navController)
}
) {
Navigation(navController = navController) // TODO This controls the navigation between different screens
}
}
My seperate created TopAppBar:
@Composable
fun TopAppBar1(
scope: CoroutineScope,
scaffoldState: ScaffoldState,
text: String,
onIconClick: () -> Unit
) {
TopAppBar(
title = { Text(text = text, fontSize = 18.sp) },
navigationIcon = {
IconButton(onClick = {
scope.launch {
withContext(Dispatchers.IO) { // should I keep this coroutine on background thread ?
scaffoldState.drawerState.open()
}
}
}) {
Icon(
Icons.Filled.Menu, "Menu",
Modifier.clickable { onIconClick.invoke()})
}
},
backgroundColor = LightBlue,
contentColor = MaterialTheme.colors.onPrimary,
)
}
ProfileScreen:
@SuppressLint("UnusedMaterialScaffoldPaddingParameter")
@Composable
fun ProfileScreen1() {
val scaffoldState = rememberScaffoldState(rememberDrawerState(DrawerValue.Closed))
val scope = rememberCoroutineScope()
Scaffold(
topBar = {
TopAppBar1(scope = scope, scaffoldState = scaffoldState, text = "Profile") {
scope.launch { scaffoldState.drawerState.currentValue } <----------- Trailing Lambda
}
},
content = {
ActualBackground() // Background
Column(
modifier = Modifier
.fillMaxSize(),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally,
) { // Content }
I show you what I did:
TopAppBar.kt:
@Composable
fun TopAppBarScreen(
title: String = "",
screen: String,
navController: NavController
) {
TopAppBar(
title = {
Text(
text = title,
style = Typography.h2
)
},
navigationIcon = {
IconButton(
onClick = {
navController.navigate(screen)
}
) {
Icon(Icons.Filled.ArrowBack, "backIcon")
}
},
backgroundColor = Color.Background,
contentColor = Color.BackgroundDarkGrey,
elevation = 0.dp,
)
}
Navigation.kt
@Composable
fun Navigation() {
val navController = rememberNavController()
val viewModel = hiltViewModel<CountrySelectorViewModel>()
val userViewModel = InputViewModel(LocalContext.current)
NavHost(
navController = navController,
startDestination = Screen.WELCOME_SCREEN
) {
composable(Screen.WELCOME_SCREEN) {
WelcomeScreen(navController = navController)
}
}
Screen:
object Screen {
const val WELCOME_SCREEN = "WelcomeScreen"
}
When I call my TopAppBar:
TopAppBarScreen(
screen = Screen.WELCOME_SCREEN,
navController = navController
)
Look at how the navigation works and it's the same if you are using a button to change screen.
I hope this can help you
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.