如何为Jetpack Compose BottomSheet实现状态变更回调/监听机制
Jetpack Compose BottomSheet 状态变更回调实现方案
实现方式1:全局监听所有状态变更(等价于原生onStateChanged回调)
通过snapshotFlow监听ModalBottomSheetState的状态变化,可覆盖所有触发Sheet状态变更的场景,包括手势下滑、返回键关闭、代码调用关闭等。
// 首先声明ModalBottomSheet状态 val modalState = rememberModalBottomSheetState(initialValue = ModalBottomSheetValue.Hidden) val coroutineScope = rememberCoroutineScope() // 添加状态监听逻辑 LaunchedEffect(modalState) { snapshotFlow { modalState.currentValue } // 仅状态发生变化时触发回调,避免重复执行 .distinctUntilChanged() .collect { newState -> when(newState) { // BottomSheet完全折叠/隐藏完成的回调 ModalBottomSheetValue.Hidden -> { // 在此处执行后续任务,比如视图转位图逻辑 captureComposableToBitmap() } // BottomSheet完全展开完成的回调 ModalBottomSheetValue.Expanded -> { // 可自定义展开完成后的逻辑 } // BottomSheet半展开完成的回调(仅开启半展开属性时生效) ModalBottomSheetValue.HalfExpanded -> { // 可自定义半展开完成后的逻辑 } } } } // 原有关闭Sheet的逻辑无需修改 val closeSheet: () -> Unit = { coroutineScope.launch { modalState.hide() } }
如果需要实现等价于原生onSlide的滑动偏移监听,可添加如下逻辑:
LaunchedEffect(modalState) { snapshotFlow { modalState.offset } .collect { currentOffset -> // 计算0-1区间的滑动偏移量 val slideOffset = currentOffset / modalState.offsetBound // 在此处处理滑动过程中的实时逻辑 } }
实现方式2:仅监听代码调用关闭的完成状态(适配你的场景更简洁)
如果你的场景仅需要在点击Sheet内按钮关闭Sheet后执行后续逻辑,不需要监听其他来源的关闭事件,可以直接利用hide()方法是挂起函数的特性,等待折叠完成后再执行后续任务,代码更精简:
val onSheetButtonClick: () -> Unit = { coroutineScope.launch { // 该挂起方法会等到BottomSheet完全折叠后才会继续执行后续代码 modalState.hide() // 直接在此处执行转位图逻辑即可,不会出现Sheet未折叠完成的问题 captureComposableToBitmap() } }
适配说明
- 如果你使用的是Compose Material 3版本的
ModalBottomSheet,对应的状态类为SheetState,隐藏状态枚举为SheetValue.Hidden,上述用法完全一致。 - 两种方案都能保证转位图逻辑执行时,BottomSheet已经完全隐藏,不会出现在截图中的问题。
内容的提问来源于stack exchange,提问作者ankuranurag2
相关产品推荐
相关产品推荐

