I followed this document from the developer site.
I want to display the text in an OutlinedTextField
from a user input, and have it survive configuration changes.
With the code below, when the user inputs the text from the keyboard, OutlinedTextField
doesn't update the text.
HelloContent(name = city.name, onNameChange = { city.name = it})//Doesn't work
However this line of code works properly:
HelloContent(name = temp, onNameChange = { temp = it})//Work
Below is the code which I use to implement:
@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)})
}
Could you help me to fix the first code block to work?
HelloContent(name = city.name, onNameChange = { city.name = it})//Doesn't work
The TextField
will not be updated because you are only modifying city.name
not the actual mutableState City
object so there is nothing that tells the composer
to trigger an update (re-composition
).
So modify your first HelloContent
composable like this.
HelloContent(name = city.name, onNameChange = { city = city.copy(name = it)})
changing this line
onNameChange = { city.name = it}
to this
onNameChange = { city = city.copy(name = it)}
will make sure your TextField
gets updated(re-composed
).
Keep in mind, invoking .copy()
on data classes guarantees a new instance will be created (provided that you supplied a new value to one of its properties/fields), which is needed by Compose
to trigger re-composition
.