You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Jetpack Compose中如何将Navigation Drawer放置在TopAppBar下方

问题描述
  • 我目前使用Jetpack Compose开发一款包含多个页面的应用,可通过Navigation Drawer实现各页面间的导航跳转。
  • 需求是将Navigation Drawer放置在*TopAppBar(即Toolbar工具栏)*的下方,效果参考如下动图:
    Navigation Drawer位于TopAppBar下方效果演示

以下是当前实现的可组合函数代码:

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 01:15:33