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

隐藏软键盘后Modal Bottom Sheet无法正常显示的问题

问题:软键盘打开时隐藏后无法显示Modal Bottom Sheet

现象描述

当软键盘处于打开状态时,点击按钮隐藏软键盘并调用sheetState.show(),软键盘成功隐藏,但Modal Bottom Sheet无法显示。该代码用于模拟API请求返回结果后打开sheetState的场景,且Sheet仅首次能正常显示。

示例代码

setContent {
    val sheetState = rememberModalBottomSheetState(ModalBottomSheetValue.Hidden)
    val key = LocalSoftwareKeyboardController.current
    ModalBottomSheetLayout(
        sheetState = sheetState,
        sheetContent = {
            repeat(20) {
                Text(text = "$it")
            }
        }
    ) {
        Column {
            var otpResponse by remember { mutableStateOf<Boolean?>(null) }
            if (otpResponse == false) {
                LaunchedEffect(key1 = Unit, block = {
                    delay(180)
                    otpResponse = true
                })
            }
            if (otpResponse == true) {
                LaunchedEffect(key1 = Unit, block = {
                    sheetState.show()
                })
            }
            Column {
                var string by remember { mutableStateOf("") }
                TextField(value = string, onValueChange = { string = it })
                Button(onClick = {
                    key?.hide()
                    otpResponse = false
                }) {
                    Text(text = "TEST")
                }
            }
        }
    }
}

解决方案

问题根源在于两个核心问题:

  1. LaunchedEffect触发逻辑失效:第二个LaunchedEffect用Unit作为key,仅首次组合时执行,后续otpResponse变为true时不会重新触发。
  2. 软键盘与Sheet的时序冲突:软键盘隐藏动画未完成就调用Sheet显示,导致Sheet状态更新被系统中断。

修改后的代码如下:

setContent {
    val sheetState = rememberModalBottomSheetState(ModalBottomSheetValue.Hidden)
    val key = LocalSoftwareKeyboardController.current
    
    ModalBottomSheetLayout(
        sheetState = sheetState,
        sheetContent = {
            repeat(20) {
                Text(text = "$it")
            }
        }
    ) {
        Column {
            var otpResponse by remember { mutableStateOf<Boolean?>(null) }
            
            // 监听otpResponse变化,每次状态为true时触发Sheet显示
            LaunchedEffect(otpResponse) {
                if (otpResponse == true) {
                    // 等待软键盘隐藏动画完成再显示Sheet
                    delay(200)
                    sheetState.show()
                }
            }
            
            Column {
                var string by remember { mutableStateOf("") }
                TextField(value = string, onValueChange = { string = it })
                Button(onClick = {
                    key?.hide()
                    // 直接设置为true,省略多余中间状态
                    otpResponse = true
                }) {
                    Text(text = "TEST")
                }
            }
        }
    }
}

修改说明

  • 将LaunchedEffect的key改为otpResponse,保证每次状态变化时都会执行Sheet显示逻辑。
  • 移除冗余的状态切换逻辑,按钮点击时直接设置otpResponse=true,简化代码流程。
  • 添加短暂延迟等待软键盘隐藏动画完成,避免时序冲突导致Sheet无法正常渲染。

内容的提问来源于stack exchange,提问作者sarthak gupta

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 22:45:33