Kotlin Compose中如何让Snackbar与悬浮按钮分层不遮挡?
方案一:切换到Material3 Scaffold(推荐)
你的代码中混用了Material2和Material3组件(如androidx.compose.material3.Text),改用Material3的Scaffold组件可自动处理Snackbar与居中FAB的遮挡问题——当Snackbar显示时,FAB会自动上移避让。
修改后的完整代码
@Composable fun CreateYourOwnDictionaryScreen( navController: NavController, viewModel: CreateYourOwnDictionaryViewModel = hiltViewModel() ) { val snackbarHostState = rememberSnackbarHostState() val state = viewModel.state.value val scope = rememberCoroutineScope() Scaffold( snackbarHost = { SnackbarHost(hostState = snackbarHostState) }, topBar = { TopAppBar( title = { Text( text = "your dictionaries", modifier = Modifier.fillMaxWidth(), color = Color.White, fontSize = 22.sp ) }, navigationIcon = { IconButton(onClick = { navController.navigate(Screen.MainScreen.route) }) { Icon( imageVector = Icons.Filled.ArrowBack, contentDescription = "Go Back", tint = Color.White ) } }, colors = TopAppBarDefaults.topAppBarColors( containerColor = bar ) ) }, floatingActionButtonPosition = FabPosition.Center, floatingActionButton = { FloatingActionButton( onClick = { navController.navigate(Screen.CreateDicScreen.route) }, containerColor = bar ) { Icon(Icons.Filled.Add, contentDescription = "fab", tint = Color.White) } } ) { innerPadding -> Box( modifier = Modifier .background(MaterialTheme.colors.background) .padding(innerPadding) ) { Column( modifier = Modifier .fillMaxSize() .padding(16.dp) ) { LazyColumn(modifier = Modifier.fillMaxSize()) { items(state.dictionaries) { dictionary -> CreateYourOwnDictionaryItem( dictionary = dictionary, modifier = Modifier .fillMaxWidth() .clickable {}, onDeleteClick = { viewModel.onEvent( CreateYourOwnDictionaryEvents.DeleteDictionary(dictionary) ) scope.launch { val result = snackbarHostState.showSnackbar( message = "dictionary is deleted", actionLabel = "Undo", duration = SnackbarDuration.Short ) if (result == SnackbarResult.ActionPerformed) { viewModel.onEvent( CreateYourOwnDictionaryEvents.RestoreDictionary(dictionary) ) } } }, onEditClick = {} ) } } } } } }
关键修改点
- 替换Material2组件导入为Material3:
androidx.compose.material3.Scaffold、androidx.compose.material3.TopAppBar、androidx.compose.material3.FloatingActionButton - 用
SnackbarHostState单独管理Snackbar,替代原scaffoldState中的snackbarHostState - 给
TopAppBar配置colors参数设置背景色(Material3不再支持直接的backgroundColor参数) - 内容区域添加
innerPadding,避免被TopAppBar和FAB遮挡 - Material3 Scaffold会自动处理Snackbar与FAB的交互,无需手动调整位置
方案二:自定义SnackbarHost位置(兼容Material2)
若暂时不想切换到Material3,可通过自定义SnackbarHost的位置,让Snackbar避开FAB区域:
修改Scaffold配置
Scaffold( scaffoldState = scaffoldState, topBar = { /* 保留原有TopAppBar代码 */ }, floatingActionButtonPosition = FabPosition.Center, floatingActionButton = { /* 保留原有FAB代码 */ }, snackbarHost = { hostState -> SnackbarHost(hostState) { snackbarData -> Box( modifier = Modifier .fillMaxWidth() .padding(bottom = 80.dp) // 上移Snackbar,避开FAB .padding(horizontal = 16.dp) ) { Snackbar( modifier = Modifier.align(Alignment.Center), snackbarData = snackbarData ) } } } ) { /* 保留原有内容区域代码 */ }
这种方式通过手动调整Snackbar的底部内边距,让它显示在FAB上方,避免遮挡。
内容的提问来源于stack exchange,提问作者NewPartizal
相关产品推荐
相关产品推荐

