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

Jetpack Compose中ViewModel已更新,UI却未重组的问题求助

Jetpack Compose ViewModel更新后未触发UI重组的问题解决

你的代码核心问题出在按钮点击事件的写法错误,导致ViewModel的更新函数从未被调用,所以看起来ViewModel值没触发UI重组(实际是值根本没被修改)。

错误位置

在DisplayOnScreen组件的Button代码中:

Button(onClick = {changeText}){ // 错误:仅引用函数,未执行调用
    Text("Click")
}

这里的{changeText}只是把函数本身作为Lambda返回值,没有实际调用changeText()函数,所以点击按钮不会触发ViewModel的testVar更新。

修正方案

有两种正确写法:

  1. 直接传递函数引用(推荐,更简洁):
Button(onClick = changeText){
    Text("Click")
}
  1. 在Lambda中显式调用函数:
Button(onClick = { changeText() }){
    Text("Click")
}

修正后的完整代码

TestViewModel.kt(无改动):

class TestViewModel: ViewModel(){
    var testVar by mutableStateOf("Hi")

    fun changeText(){
        testVar = "New"
    }
}

MainActivity.kt(仅修正DisplayOnScreen):

class MainActivity: ComponentActivity(){
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
                TestAppTheme {
                        Surface(
                                modifier = Modifier.fillMaxSize(),
                                color = MaterialTheme.colorScheme.background
                        ) {
                                Greeting(viewModel = viewModel())
                        }
                }
        }
    }
}

@Composable
fun Greeting(viewModel: TestViewModel = viewModel()) {
        DisplayOnScreen(testVar = viewModel.testVar, changeText = {viewModel.changeText()})
}

@Composable
fun DisplayOnScreen(testVar: String, changeText: () -> Unit){
        Column() {
                Text(testVar)
                // 修正后的Button
                Button(onClick = changeText){
                        Text("Click")
                }
        }
}

@Preview (showBackground = true, showSystemUi = true)
@Composable
fun GreetingPreview(viewModel: TestViewModel = viewModel()) {
        TestAppTheme {
                Greeting(viewModel = viewModel())
        }
}

对比可运行示例代码的差异

你可以看正常运行的示例代码中,Button的onClick是这样写的:

Button ( onClick = {convertTemp(textState) }
) { Text("Convert Temperature") }

这里是显式调用了函数,而你的错误代码只是引用了函数,没有执行调用,这就是两者的核心区别。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 18:55:12