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

Jetpack Compose中如何让Snackbar显示在Scaffold的BottomNavBar上方

解决方案

你遇到的层级问题由两个原因导致:一是底部导航设置了zIndex(5f),而放在内容区域的自定义Snackbar默认zIndex为0,层级更低;二是未利用Scaffold原生提供的snackbarHost插槽(该插槽的层级默认高于底部导航栏)。

方案1(推荐,符合Compose规范)

直接将自定义的DefaultSnackbar放到Scaffold的snackbarHost参数中,移除内容区域的DefaultSnackbar代码即可,Scaffold会自动处理层级关系,保证Snackbar显示在底部导航上方。
修改后的Scaffold代码如下:

Scaffold(
    topBar = {
        // 原有SearchBar逻辑保持不变
        SearchBar(
            query = query,
            onQueryChange = viewModel::onQueryChange,
            selectedCategory = selectedCategory,
            onSelectedCategoryChanged = viewModel::onSelectedCategoryChanged,
            onToggleTheme = viewModel::onToggleTheme,
            searchRecipe = {
                if (viewModel.selectedCategory.value?.value == "Milk") {
                    snackbarController.getScope().launch {
                        snackbarController.showSnackbar(
                            scaffoldSate= scaffoldState,
                            message = "Milk is in Snack",
                            actionLabel = "Hide",
                        )
                    }
                } else {
                    viewModel.searchRecipe()
                }
            }
        )
    },
    bottomBar = { BottomNav() },
    scaffoldState = scaffoldState,
    // 替换原来的snackbarHost配置,直接传入自定义Snackbar
    snackbarHost = {
        DefaultSnackbar(
            snackbarHostState = scaffoldState.snackbarHostState,
            onDismiss = { scaffoldState.snackbarHostState.currentSnackbarData?.dismiss() },
            modifier = Modifier
        )
    },
) { paddingValues ->
    Box(modifier = Modifier
        .background(MaterialTheme.colors.background)
        .fillMaxSize()
        // 加上Scaffold传入的padding,避免内容被顶部/底部导航遮挡
        .padding(paddingValues)
    ) {
       ...
       原有其他内容代码保持不变,删除此处的DefaultSnackbar调用
       ...

        CircularIndeterminateProgressBar(display = viewModel.isLoading.value)
    }
}

方案2(兼容原有写法)

如果需要继续将Snackbar放在内容区域的Box内,只需给DefaultSnackbar设置高于底部导航的zIndex,同时增加底部边距避免重叠即可:

DefaultSnackbar(
    snackbarHostState = scaffoldState.snackbarHostState,
    onDismiss = { scaffoldState.snackbarHostState.currentSnackbarData?.dismiss()},
    modifier = Modifier
        .align(Alignment.BottomCenter)
        // zIndex高于底部导航的5f即可
        .zIndex(6f)
        // 底部留空避免和底部导航重叠,56.dp是Material Design底部导航的标准高度
        .padding(bottom = 56.dp)
)

内容的提问来源于stack exchange,提问作者Jeevan Rupacha

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 04:24:00