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

使用WindowInsets.isImeVisible导致Jetpack Compose状态丢失求助

问题分析与解决方案

问题根源

你在ChatScreen的默认参数中直接实例化ChatScreenViewModel,而WindowInsets.isImeVisible是会触发Composable重组的状态值。每次键盘弹出/隐藏触发重组时,ViewModel会被重新创建,导致textFieldState、messageListState等状态全部重置为初始值。

修复步骤

  1. 正确获取ViewModel实例
    不要在Composable默认参数里直接new ViewModel,改用Jetpack Compose提供的viewModel()函数获取实例,确保ViewModel生命周期与Composable绑定,不会随重组重复创建。

    修改后的ChatScreen代码:

    @OptIn(ExperimentalLayoutApi::class)
    @Preview(showBackground = true)
    @Composable
    fun ChatScreen(viewModel: ChatScreenViewModel = viewModel()) { // 改用viewModel()函数获取实例
    
        val messages = viewModel.messageListState
        val listState = viewModel.messageListScrollState
        val keyboardVisibility = WindowInsets.isImeVisible
    
        // 监听键盘弹出,自动滚动到底部
        LaunchedEffect(keyboardVisibility) {
            if (keyboardVisibility && messages.isNotEmpty()) {
                listState.animateScrollToItem(messages.size - 1)
            }
        }
    
        Column(/* 你的布局配置 */) {
            LazyColumn(state = listState) {
                items(messages) { msg ->
                    Text(msg)
                }
            }
            TextField(
                value = viewModel.textFieldState.value,
                onValueChange = { viewModel.textFieldState.value = it },
                label = { Text("输入消息") }
            )
        }
    }
    
  2. ViewModel代码保持不变
    你的ChatScreenViewModel代码无需修改,状态容器使用mutableStateOf和mutableStateListOf的写法是正确的:

    class ChatScreenViewModel: ViewModel() {
        val messageListScrollState = LazyListState()
        val textFieldState = mutableStateOf("")
        val messageListState = mutableStateListOf<String>(
                "dummy message 1",
                "dummy message 2",
                "dummy message 3",
                "dummy message 4"
            )
    }
    

额外说明

  • 使用viewModel()函数需要依赖androidx.lifecycle.viewmodel.compose:viewmodel-compose库,确保项目build.gradle中已引入该依赖。
  • LaunchedEffect会在keyboardVisibility变化时执行滚动逻辑,仅触发必要的操作,避免冗余重组。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 22:52:13