Jetpack Compose中如何将Navigation Drawer放置在TopAppBar下方
问题描述
- 我目前使用
Jetpack Compose开发一款包含多个页面的应用,可通过Navigation Drawer实现各页面间的导航跳转。 - 需求是将Navigation Drawer放置在*
TopAppBar(即Toolbar工具栏)*的下方,效果参考如下动图:
以下是当前实现的可组合函数代码:
fun Home(navController: NavHostController) { val scaffoldState = rememberScaffoldState() val coroutineScope = rememberCoroutineScope() Scaffold( topBar = { TopAppBar( title = { Text( buildAnnotatedString { append("Hello World") pushStyle(SpanStyle(fontWeight = FontWeight.Medium, fontSize = 12.sp)) append("\nhelloworld@gmail.com") pushStyle(SpanStyle(fontWeight = FontWeight.Light, fontSize = 10.sp)) } ) }, navigationIcon = { IconButton(onClick = { coroutineScope.launch { scaffoldState.drawerState.open() } }) { Icon( imageVector = Icons.Outlined.Menu, contentDescription = null ) } } ) }, drawerContent = {}, scaffoldState = scaffoldState, drawerContentColor = MaterialTheme.colors.onBackground, content = { HomeScreenContent(scaffoldState, navController) }, floatingActionButton = { ExtendedFloatingActionButton( text = { Text(text = "Compose") }, onClick = { navController.navigate("CreateMsg") }, modifier = Modifier.padding(0.dp), icon = { Icon( imageVector = Icons.Outlined.Create, contentDescription = null, tint = Color.White, ) }, shape = CircleShape, backgroundColor = MaterialTheme.colors.primary ) } ) }
实现方案
默认Scaffold的Navigation Drawer会覆盖在TopAppBar上层,从屏幕最左侧边缘滑出。要实现抽屉在TopAppBar下方的效果,不要把TopAppBar传入Scaffold的topBar参数,而是用Column垂直排列TopAppBar和带抽屉的Scaffold,让Scaffold只占TopAppBar下方的剩余屏幕空间,抽屉自然就只会在该区域内滑出。
调整后的代码示例:
fun Home(navController: NavHostController) { val scaffoldState = rememberScaffoldState() val coroutineScope = rememberCoroutineScope() Column(modifier = Modifier.fillMaxSize()) { // 顶部固定放置TopAppBar TopAppBar( title = { Text( buildAnnotatedString { append("Hello World") pushStyle(SpanStyle(fontWeight = FontWeight.Medium, fontSize = 12.sp)) append("\nhelloworld@gmail.com") pushStyle(SpanStyle(fontWeight = FontWeight.Light, fontSize = 10.sp)) } ) }, navigationIcon = { IconButton(onClick = { coroutineScope.launch { scaffoldState.drawerState.open() } }) { Icon( imageVector = Icons.Outlined.Menu, contentDescription = "打开导航抽屉" ) } } ) // Scaffold占满TopBar下方剩余空间,抽屉仅在该区域内展示 Scaffold( scaffoldState = scaffoldState, drawerContent = { // 在此处编写抽屉菜单项内容即可 }, drawerContentColor = MaterialTheme.colors.onBackground, modifier = Modifier.weight(1f), content = { HomeScreenContent(scaffoldState, navController) }, floatingActionButton = { ExtendedFloatingActionButton( text = { Text(text = "Compose") }, onClick = { navController.navigate("CreateMsg") }, modifier = Modifier.padding(0.dp), icon = { Icon( imageVector = Icons.Outlined.Create, contentDescription = null, tint = Color.White, ) }, shape = CircleShape, backgroundColor = MaterialTheme.colors.primary ) } ) } }
该写法无需额外调整抽屉偏移量、遮罩颜色参数,抽屉滑出时的半透明遮罩会自动只覆盖TopAppBar下方的内容区域,和示例动图效果完全一致。
内容的提问来源于stack exchange,提问作者Sumit Shukla
相关产品推荐
相关产品推荐

