如何实现ModalBottomSheetLayout弹出时背景变暗且不可点击?
ModalBottomSheetLayout 弹窗背景变暗且不可点击的实现方案
问题场景
使用ModalBottomSheetLayout时,需要实现:底部弹窗打开时,背景区域变暗且无法点击。但遇到以下问题:
- 设置
screenColor为Color.Unspecified时,背景不可点击但无变暗效果; - 手动添加背景遮罩实现变暗后,背景区域变为可点击,底层控件会被误触发。
解决方案
无需手动添加遮罩层,直接利用ModalBottomSheetLayout自带的scrimColor属性即可同时实现背景变暗和不可点击的需求:
- 移除代码中手动添加的遮罩
Box; - 在
ModalBottomSheetLayout中配置scrimColor参数,根据弹窗状态动态设置半透明黑色; - 移除冗余的
bottomSheetOpen状态,直接通过bottomSheetState的状态判断弹窗是否显示。
修改后的完整代码
@OptIn(ExperimentalMaterialApi::class) @Composable fun ForpostScreen(forpostViewModel: ForpostViewModel = koinViewModel()) { val scope = rememberCoroutineScope() val viewState = forpostViewModel.forpostViewState.observeAsState() val bottomSheetState = rememberModalBottomSheetState( initialValue = ModalBottomSheetValue.Hidden ) ModalBottomSheetLayout( sheetState = bottomSheetState, sheetContent = { Box(modifier = Modifier .fillMaxWidth() .height(500.dp)) { Image( painter = painterResource(id = R.drawable.botton_sheet_top_line), contentDescription = "Линия", modifier = Modifier .height(20.dp) .width(70.dp) .padding(top = 10.dp) .align(Alignment.TopCenter) ) Text( text = stringResource(id = R.string.all_cams_button), color = colorResource(id = R.color.title_text_color), fontWeight = FontWeight(600), fontSize = 25.sp, modifier = Modifier .padding(top = 30.dp) .align(Alignment.TopCenter) ) } }, sheetShape = RoundedCornerShape(topStart = 25.dp, topEnd = 25.dp), sheetElevation = 12.dp, // 核心:根据弹窗状态设置背景遮罩颜色 scrimColor = if (bottomSheetState.isVisible) Color.Black.copy(alpha = 0.5f) else Color.Transparent ) { Surface(color = Color.White) { Column { Button( onClick = { scope.launch { bottomSheetState.show() } }, colors = ButtonDefaults.buttonColors(colorResource(id = R.color.button_color)), shape = RoundedCornerShape(15.dp), modifier = Modifier .padding(top = 20.dp, start = 20.dp) .height(30.dp) .width(130.dp), contentPadding = PaddingValues(bottom = 0.dp), content = { Text( text = stringResource(id = R.string.all_cams_button), color = Color.White, fontWeight = FontWeight(400) ) } ) Text( modifier = Modifier.padding(top = 50.dp, start = 20.dp), text = "Репина, 1 Б", color = colorResource(id = R.color.title_text_color), fontWeight = FontWeight(700), fontSize = 18.sp, letterSpacing= 1.sp ) ButtonsLazyColumn( listItem = listOf("Двор", "Подъезд", "Парковка", "Въезд", "Пост охраны"), height = 50, modifierPaddingStart = 20, modifierPaddingTop = 15, modifierPaddingEnd = 10, ) Surface(modifier = Modifier .fillMaxWidth() .padding(top = 20.dp) .height(220.dp) .background(Color.Black)) { when (viewState.value) { is ForpostViewState.Loading -> { VideoLoadingView() } is ForpostViewState.Load -> { PlayerView(forpostViewModel = forpostViewModel) } else -> {} } } Divider( modifier = Modifier.padding(top = 100.dp), color = colorResource(id = R.color.sevstar_gray_light), thickness = 1.dp ) ButtonsLazyColumn( listItem = listOf("1 сек", "1 мин", "5 мин", "10 мин", "30 мин"), height = 50, modifierPaddingStart = 20, modifierPaddingTop = 15, modifierPaddingEnd = 10 ) Divider( modifier = Modifier.padding(top = 20.dp), color = colorResource(id = R.color.sevstar_purple), thickness = 1.dp ) } } } LaunchedEffect(key1 = viewState, block = { forpostViewModel.obtainEvent(event = ForpostEvents.EnterScreen) }) }
关键说明
scrimColor是ModalBottomSheetLayout的内置属性,专门用于控制弹窗打开时的背景遮罩颜色;- 当弹窗显示时,
scrimColor会自动覆盖在底层内容之上,既实现变暗效果,又阻止底层控件的点击事件; - 移除了冗余的
bottomSheetOpen状态,直接通过bottomSheetState.isVisible判断弹窗状态,代码更简洁可靠。
内容的提问来源于stack exchange,提问作者ge0graff
相关产品推荐
相关产品推荐

