You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android Compose:关闭Bottom Sheet时屏幕冻结问题求助

Jetpack Compose BottomSheet关闭后界面无响应问题修复

问题描述

使用Jetpack Compose开发Android应用时,拖动Bottom Sheet向下关闭或按返回键关闭后,屏幕完全无响应,必须重启应用才能恢复。

问题根源

  1. 协程触发时机错误:在BottomSheet组件中直接调用scope.launch执行bottomSheetState.expand(),未使用LaunchedEffect,导致组件每次重组都会重复触发展开操作,引发状态冲突。
  2. 显示控制逻辑错误:直接将BottomSheet嵌入CustomCard的内容区域,未通过Boolean状态控制其显示/隐藏,关闭后组件状态未同步更新,导致界面阻塞。
  3. 关闭回调未同步状态: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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 18:52:48