BottomSheetScaffold展开非全屏时如何对后方内容做模糊或着色处理
Jetpack Compose BottomSheetScaffold 背景着色/模糊实现方案
完全可以实现,以下是两种常用的落地方案:
方案1:添加动态遮罩层
这是兼容性最好的实现方式,无需适配高版本系统:
- 首先通过
rememberBottomSheetScaffoldState获取BottomSheet的状态,监听其展开进度 - 在Scaffold的主内容区域外层包裹
Box容器,在主内容之上、BottomSheet之下新增一层遮罩View - 遮罩的透明度和BottomSheet的展开进度绑定,展开到半高时透明度同步调整到对应比例,完全收起时隐藏遮罩
- 如果需要模糊效果,可在遮罩层应用
RenderEffect实现毛玻璃效果
示例代码:
val scaffoldState = rememberBottomSheetScaffoldState() val sheetProgress = scaffoldState.bottomSheetState.progress val coroutineScope = rememberCoroutineScope() BottomSheetScaffold( scaffoldState = scaffoldState, sheetContent = { /* 你的BottomSheet内容 */ }, sheetPeekHeight = 0.dp ) { innerPadding -> Box(modifier = Modifier.padding(innerPadding)) { // 原始主内容 MainContent() // 背景遮罩 if (scaffoldState.bottomSheetState.isVisible) { Box( modifier = Modifier .fillMaxSize() // 半透明着色,可修改颜色实现不同效果 .background(Color.Black.copy(alpha = sheetProgress * 0.6f)) // 拦截点击事件,避免点到下层内容 .clickable(indication = null, interactionSource = remember { MutableInteractionSource() }) { // 点击遮罩收起BottomSheet可选 coroutineScope.launch { scaffoldState.bottomSheetState.hide() } } // 模糊效果可选,API 31+生效 .then( if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { Modifier.graphicsLayer { renderEffect = RenderEffect.createBlurEffect( radiusX = sheetProgress * 20f, radiusY = sheetProgress * 20f, TileMode.DECAL ) } } else Modifier ) ) } } }
方案2:直接给主内容添加效果
如果不需要拦截背景点击,也可以直接给主内容绑定效果:
- 直接给主内容的Modifier添加
graphicsLayer属性,根据BottomSheet展开进度调整透明度、模糊参数即可 - 该方案代码更简洁,适合不需要拦截背景点击的场景
注意事项
- 模糊效果
RenderEffect仅支持Android 12(API 31)及以上系统,低版本建议降级为半透明遮罩实现,避免运行时报错 - 如果你使用的是Material3组件库的
ModalBottomSheet,组件本身自带scrim属性,直接修改该属性的颜色即可实现背景着色,无需自定义实现
内容的提问来源于stack exchange,提问作者Cyril
相关产品推荐
相关产品推荐

