So i am new to Jetpack compose and am trying to figure out how to add the drawer functionality to a button on my view.
A counterpart question that i found for my question in relation to the XML imperative approach Navigation Drawer without Actionbar
Would love to learn about the approach to the same.
You can accomplish this in many ways i guess. I will only post 2 alternatives
1- You can use Scaffold with drawerContent
and adding your layout as this content
val scaffoldState = rememberScaffoldState()
val coroutineScope = rememberCoroutineScope()
val openDrawer: () -> Unit = { coroutineScope.launch { scaffoldState.drawerState.open() } }
val closeDrawer: () -> Unit = { coroutineScope.launch { scaffoldState.drawerState.close() } }
Scaffold(
scaffoldState = scaffoldState,
drawerContent = {
AppDrawer(
currentRoute = currentRoute,
navigateToHome = {
currentRoute = Routes.HOME_ROUTE
navController.popBackStack()
navController.navigate(currentRoute)
},
navigateToSettings = {
currentRoute = Routes.SETTINGS_ROUTE
navController.popBackStack()
navController.navigate(currentRoute)
},
closeDrawer = closeDrawer
)
},
) {
NavHost(
navController = navController,
startDestination = Routes.HOME_ROUTE
) {
composable(Routes.HOME_ROUTE) {
HomeComponent()
}
composable(Routes.SETTINGS_ROUTE) {
SettingsComponent()
}
}
}
Our drawer content
@Composable
fun AppDrawer(
currentRoute: String,
navigateToHome: () -> Unit,
navigateToSettings: () -> Unit,
closeDrawer: () -> Unit
) {
Column(modifier = Modifier.fillMaxSize()) {
DrawerHeader()
DrawerButton(
icon = Icons.Filled.Home,
label = "Home",
isSelected = currentRoute == Routes.HOME_ROUTE,
action = {
if (currentRoute != Routes.HOME_ROUTE) {
navigateToHome()
}
closeDrawer()
}
)
DrawerButton(
icon = Icons.Filled.Settings,
label = "Settings",
isSelected = currentRoute == Routes.SETTINGS_ROUTE,
action = {
if (currentRoute != Routes.SETTINGS_ROUTE) {
navigateToSettings()
}
closeDrawer()
}
)
}
}
You need to set scaffoldState
to have drawer to be able to open or close with other interactions other than drawable behavior.
openDrawer
and closeDrawer
lambdas are required if you need to open or close drawer like touching an item on drawer on content.
2- Using ModalDrawer
@Composable
private fun ModalDrawerComponent() {
val drawerState = rememberDrawerState(DrawerValue.Closed)
val coroutineScope = rememberCoroutineScope()
val openDrawer: () -> Unit = { coroutineScope.launch { drawerState.open() } }
val closeDrawer: () -> Unit = { coroutineScope.launch { drawerState.close() } }
var selectedIndex by remember { mutableStateOf(0) }
ModalDrawer(
drawerState = drawerState,
drawerContent = {
ModalDrawerContentHeader()
Divider()
ModelDrawerContentBody(
selectedIndex,
onSelected = {
selectedIndex = it
},
closeDrawer = closeDrawer
)
},
content = {
Column(modifier = Modifier.fillMaxSize()) {
// ModalDrawerTopAppBar(openDrawer)
ModalContent(openDrawer)
}
}
)
}
With ModalDrawer you set your Content as you wish if you don't want to add TopAppBar you just don't add it inside content. I commented it here to display that it's not there.
You can check repo that contains implementations here.