Android Compose:关闭Bottom Sheet时屏幕冻结问题求助
Jetpack Compose BottomSheet关闭后界面无响应问题修复
问题描述
使用Jetpack Compose开发Android应用时,拖动Bottom Sheet向下关闭或按返回键关闭后,屏幕完全无响应,必须重启应用才能恢复。
问题根源
- 协程触发时机错误:在BottomSheet组件中直接调用
scope.launch执行bottomSheetState.expand(),未使用LaunchedEffect,导致组件每次重组都会重复触发展开操作,引发状态冲突。 - 显示控制逻辑错误:直接将BottomSheet嵌入CustomCard的内容区域,未通过Boolean状态控制其显示/隐藏,关闭后组件状态未同步更新,导致界面阻塞。
- 关闭回调未同步状态:
onDismiss回调仅预留了save逻辑,未更新控制BottomSheet显示的状态,导致组件仍处于异常渲染状态。
修复步骤及代码示例
1. 父组件添加BottomSheet显示控制状态
在包含Scaffold的Composable中,添加用于控制BottomSheet显示的状态:
// 控制颜色选择BottomSheet的显示状态 var showColorPickerSheet by remember { mutableStateOf(false) } // 原有的字体颜色设置展开状态 var fontColorSettingExpand by remember { mutableStateOf(false) }
2. 修改CustomCard的点击逻辑
调整CustomCard的点击事件,触发BottomSheet显示状态的更新,不再直接在Card内容中嵌入BottomSheet:
CustomCard( title = "Color", isExpandedInitially = fontColorSettingExpand, onItemClick = { fontColorSettingExpand = !fontColorSettingExpand // 点击打开BottomSheet showColorPickerSheet = true } ) { // 这里放置Color设置的其他配置项,不再包含BottomSheet }
3. 独立控制BottomSheet的渲染
在Scaffold的content区域内,根据状态条件渲染BottomSheet:
Scaffold( modifier = Modifier.fillMaxSize(), scaffoldState = scaffoldState, topBar = { AppBar(...) }, content = { paddingValue -> Box( modifier = Modifier .fillMaxSize() .padding(top = paddingValue.calculateTopPadding()) ) { Column( modifier = Modifier .fillMaxWidth() .padding(16.dp) .verticalScroll(rememberScrollState()) ) { // Night Mode设置区域 // Font设置区域 // Color设置区域(即上述的CustomCard) } // 根据状态控制BottomSheet的显示 if (showColorPickerSheet) { BottomSheet( onDismiss = { showColorPickerSheet = false // 执行保存逻辑 // saveColorSettings(...) } ) } } } )
4. 修复BottomSheet内部的协程调用
使用LaunchedEffect确保bottomSheetState.expand()仅在组件初始化时执行一次:
@Composable fun BottomSheet( onDismiss: () -> Unit ) { val bottomSheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true) val scope = rememberCoroutineScope() // 仅在组件首次组合时触发展开操作 LaunchedEffect(Unit) { bottomSheetState.expand() } ModalBottomSheet( onDismissRequest = { onDismiss() }, sheetState = bottomSheetState, dragHandle = { BottomSheetDefaults.DragHandle() } ) { ColorPicker() } }
额外检查
确认ColorPicker组件中不存在阻塞主线程的操作(如同步IO、无限循环等),这类操作也可能导致界面无响应。
内容的提问来源于stack exchange,提问作者Ftm Amani
相关产品推荐
相关产品推荐

