Jetpack Compose TextField 在输入新字符时不更新

Zap*_*ans 8 android kotlin android-jetpack-compose compose-recomposition mutablestateof

我从开发者网站上关注了这份文档。我想显示用户输入中的文本OutlinedTextField,并使其在配置更改后保持不变。

使用下面的代码,当用户从键盘输入文本时,OutlinedTextField不会更新文本。

HelloContent(name = city.name, onNameChange = { city.name = it})//Doesn't work
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

然而这行代码可以正常工作:

HelloContent(name = temp, onNameChange = { temp = it})//Work
Run Code Online (Sandbox Code Playgroud)

下面是我用来实现的代码:

@Composable
fun HelloScreen() {
    var city by rememberSaveable(stateSaver = CitySaver) {
        mutableStateOf(City("Hanoi","VietNam"))
    }
    var temp by rememberSaveable {
        mutableStateOf("")
    }
    Column {
        HelloContent(name = city.name, onNameChange = { city.name = it})//Doesn't work
        HelloContent(name = temp, onNameChange = { temp = it})//Work
    }
}
@Composable
    fun HelloContent(name: String, onNameChange: (String) -> Unit) {
        Column(modifier = Modifier.padding(16.dp)) {
            Text(
                text = "Hello, $name",
                modifier = Modifier.padding(bottom = 8.dp),
                style = MaterialTheme.typography.h5
            )
            OutlinedTextField(
                value = name,
                onValueChange = onNameChange,
                label = { Text("Name") }
            )
        }
    }
data class City(var name: String, val country: String)
val CitySaver = run {
    val nameKey = "Name"
    val countryKey = "Country"
    mapSaver(save = {mapOf(nameKey to it.name,countryKey to it.country)},
        restore = {City(it[nameKey] as String,it[countryKey] as String)})
}
Run Code Online (Sandbox Code Playgroud)

你能帮我修复第一个代码块吗?

HelloContent(name = city.name, onNameChange = { city.name = it})//Doesn't work
Run Code Online (Sandbox Code Playgroud)

z.g*_*g.y 5

不会TextField更新,因为您只是修改city.name而不是实际的mutableState City对象,因此没有任何内容告诉composer触发更新 ( re-composition)。

因此,像这样修改您的第一个HelloContent可组合项。

 HelloContent(name = city.name, onNameChange = { city = city.copy(name = it)})
Run Code Online (Sandbox Code Playgroud)

改变这条线

onNameChange = { city.name = it}
Run Code Online (Sandbox Code Playgroud)

对此

onNameChange = { city = city.copy(name = it)}
Run Code Online (Sandbox Code Playgroud)

将确保您的内容TextField得到更新(re-composed)。

请记住,调用.copy()数据类可保证创建一个新实例(前提是您为其属性/字段之一提供了新值),这是Compose触发re-composition.