自己发现了错误并修复了问题。
问题在于这一行:
val receivedItem = itemViewModel.getItem(itemId!!.toInt()).observeAsState()
receivedItem 最初从视图模型中获取一个空值,并在至少几次重组后得到更新,如下所示:
2021-08-17 14:48:52.221 7985-7985/com.example.roomcrud D/EditScreen: Item id: 3
2021-08-17 14:48:52.221 7985-7985/com.example.roomcrud D/EditScreen: receivedItem: Item(id=0, itemName=, itemPrice=0.0, quantityInStock=0)
2021-08-17 14:48:52.221 7985-7985/com.example.roomcrud D/EditScreen: Editing values: itemName - , itemPrice - 0.0, itemQuantity - 0
2021-08-17 14:48:52.255 7985-7985/com.example.roomcrud D/EditScreen: Item id: 3
2021-08-17 14:48:52.255 7985-7985/com.example.roomcrud D/EditScreen: receivedItem: Item(id=3, itemName=Mango, itemPrice=2.2, quantityInStock=27)
2021-08-17 14:48:52.255 7985-7985/com.example.roomcrud D/EditScreen: Editing values: itemName - , itemPrice - 0.0, itemQuantity - 0
2021-08-17 14:48:52.271 7985-7985/com.example.roomcrud D/EditScreen: Item id: 3
2021-08-17 14:48:52.271 7985-7985/com.example.roomcrud D/EditScreen: receivedItem: Item(id=3, itemName=Mango, itemPrice=2.2, quantityInStock=27)
2021-08-17 14:48:52.271 7985-7985/com.example.roomcrud D/EditScreen: Editing values: itemName - Mango, itemPrice - 2.2, itemQuantity - 27
2021-08-17 14:48:52.553 7985-7985/com.example.roomcrud D/EditScreen: Item id: 3
2021-08-17 14:48:52.554 7985-7985/com.example.roomcrud D/EditScreen: receivedItem: Item(id=3, itemName=Mango, itemPrice=2.2, quantityInStock=27)
2021-08-17 14:48:52.554 7985-7985/com.example.roomcrud D/EditScreen: Editing values: itemName - Mango, itemPrice - 2.2, itemQuantity - 27
2021-08-17 14:48:52.568 7985-7985/com.example.roomcrud D/EditScreen: Item id: 3
2021-08-17 14:48:52.569 7985-7985/com.example.roomcrud D/EditScreen: receivedItem: Item(id=3, itemName=Mango, itemPrice=2.2, quantityInStock=27)
2021-08-17 14:48:52.569 7985-7985/com.example.roomcrud D/EditScreen: Editing values: itemName - Mango, itemPrice - 2.2, itemQuantity - 27
所以当我记住这些值时,它们是空的。如果我随后尝试使用局部变量更新值,那么每次重组都会覆盖这些值。所以我通过使用LaunchedEffect 最小化了覆盖,并且当数据库中的实际值到达并且不为空时只更新一次值。
我现在可以编辑 TextFields 上的值了,因为它们不会在每次重组时被一遍又一遍地覆盖。
这是最终生效的更新代码:
@Composable
fun EditScreen(
itemId: String?,
navController: NavController,
itemViewModel: ItemViewModel,
onSetAppTitle: (String) -> Unit,
onShowFab: (Boolean) -> Unit
) {
LaunchedEffect(Unit) {
onSetAppTitle("Edit Item")
onShowFab(false)
}
Log.d("EditScreen", "Item id: $itemId")
val receivedItem: Item by itemViewModel.getItem(itemId!!.toInt())
.observeAsState(Item(0, "", 0.0, 0))
Log.d("EditScreen", "receivedItem: $receivedItem")
var itemName by remember { mutableStateOf(receivedItem.itemName) }
var itemPrice by remember { mutableStateOf(receivedItem.itemPrice.toString()) }
var itemQuantity by remember { mutableStateOf(receivedItem.quantityInStock.toString()) }
if (receivedItem.id != 0) {
LaunchedEffect(Unit) {
itemName = receivedItem.itemName
itemPrice = receivedItem.itemPrice.toString()
itemQuantity = receivedItem.quantityInStock.toString()
}
}
Log.d(
"EditScreen",
"Editing values: itemName - $itemName, itemPrice - $itemPrice, itemQuantity - $itemQuantity"
)
Column(
modifier = Modifier
.padding(horizontal = 32.dp, vertical = 16.dp)
.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally,
) {
OutlinedTextField(
value = itemName,
onValueChange = { itemName = it },
label = { Text("Item name") },
modifier = Modifier
.padding(top = 16.dp)
.fillMaxWidth()
)
OutlinedTextField(
value = itemPrice,
onValueChange = { itemPrice = it },
label = { Text("Item price") },
modifier = Modifier
.padding(top = 16.dp)
.fillMaxWidth()
)
OutlinedTextField(
value = itemQuantity,
onValueChange = { itemQuantity = it },
label = { Text("Item quantity") },
modifier = Modifier
.padding(top = 16.dp)
.fillMaxWidth()
)
Button(
onClick = {
if (itemViewModel.isItemValid(itemName, itemPrice, itemQuantity)) {
var updatedItem = receivedItem.copy(
itemName = itemName.trim(),
itemPrice = itemPrice.trim().toDouble(),
quantityInStock = itemQuantity.trim().toInt()
)
itemViewModel.updateItem(updatedItem)
navController.navigate("home") {
popUpTo("home") { inclusive = true }
}
}
}, modifier = Modifier
.padding(top = 16.dp)
.fillMaxWidth()
) {
Text(text = "Save")
}
}
}
希望它对未来的人有所帮助!谢谢大家的回答!