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
相关产品推荐
相关产品推荐

