在我导航出去之前,LiveData 值不会在 Jetpack Compose 中更新 UI
LiveData value not updating UI in Jetpack Compose until I navigate out
我正在从可组合项调用 increaseCount(id: String) 方法来增加 LiveData 对象列表中的参数值。该值更新得很好,但是 UI 仅在我导航出去后才显示更新。 PS: 我正在使用 BottomNavigation 视图进行导航。
有问题的可组合屏幕看起来像这样
@Composabale
fun MyScreen(navController: NavHostController, viewModel: MyViewModel){
val itemList = viewModel.itemList.observeAsState().value
LazyColumn(modifier = Modifier.fillMaxWidth()) {
items(itemList) { item: Item? ->
ItemView(item, viewModel)
}
}
}
@Composable
private fun ItemView(item: Item?, viewModel: MyViewModel) {
Row(
modifier = Modifier.padding(4.dp, 0.dp),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.End
) {
//Counter section
IconButton(onClick = { viewModel.decreaseItemCount(cartItem.itemId) }) {
Icon(
imageVector = Icons.Filled.RemoveCircleOutline,
contentDescription = "Reduce order button",
tint = Color.Gray
)
}
Text(text = "${item.itemQuantity}")
IconButton(onClick = { viewModel.increaseItemCount(item.itemId) }) {
Icon(
imageVector = Icons.Filled.AddCircleOutline,
contentDescription = "Increase order button",
tint = Color(R.color.yellow_700)
)
}
}
ViewModel 方面看起来像这样:
private val _itemList = MutableLiveData<ArrayList<Item>>()
val itemList: LiveData<List<Item>>
get() = _itemList
fun increaseItemCount(id: String) {
val theList = _itemList.value
theList?.find { item ->
item.itemId == id
}?.let { item ->
item.itemQuantity += 1
_itemList.value = theList!!
}
}
decreaseItemCount 函数类似于 increaseItemCount,唯一的区别是计数在减少。
更新对象 属性 时,LiveData
无法知道该对象已更改。并且列表仍然包含相同的对象列表。
解决方案是实际创建一个具有更新属性的新对象。数据 class 对此非常有用:将您的属性声明为 val
并使用 copy
.
更新它们
查看 Why is immutability important in functional programming?。
实时数据版本:
data class Item(val itemId: String, val itemQuantity: Int)
private val _itemList = MutableLiveData<List<Item>>()
val itemList: LiveData<List<Item>>
get() = _itemList
fun increaseItemCount(id: String) {
val theList = _itemList.value?.toMutableList() ?: return
val index = theList.indexOfFirst { it.itemId == id }
if (index == -1) return
theList[index] = theList[index].let {
it.copy(itemQuantity = it.itemQuantity + 1)
}
_itemList.value = theList
}
mutableStateListOf
版本更短更简洁:
data class Item(val itemId: String, val itemQuantity: Int)
private val _itemList = mutableStateListOf<Item>()
val itemList: List<Item> = _itemList
fun increaseItemCount(id: String) {
val index = _itemList.indexOfFirst { it.itemId == id }
if (index == -1) return
_itemList[index] = _itemList[index].let {
it.copy(itemQuantity = it.itemQuantity + 1)
}
}
我正在从可组合项调用 increaseCount(id: String) 方法来增加 LiveData 对象列表中的参数值。该值更新得很好,但是 UI 仅在我导航出去后才显示更新。 PS: 我正在使用 BottomNavigation 视图进行导航。
有问题的可组合屏幕看起来像这样
@Composabale
fun MyScreen(navController: NavHostController, viewModel: MyViewModel){
val itemList = viewModel.itemList.observeAsState().value
LazyColumn(modifier = Modifier.fillMaxWidth()) {
items(itemList) { item: Item? ->
ItemView(item, viewModel)
}
}
}
@Composable
private fun ItemView(item: Item?, viewModel: MyViewModel) {
Row(
modifier = Modifier.padding(4.dp, 0.dp),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.End
) {
//Counter section
IconButton(onClick = { viewModel.decreaseItemCount(cartItem.itemId) }) {
Icon(
imageVector = Icons.Filled.RemoveCircleOutline,
contentDescription = "Reduce order button",
tint = Color.Gray
)
}
Text(text = "${item.itemQuantity}")
IconButton(onClick = { viewModel.increaseItemCount(item.itemId) }) {
Icon(
imageVector = Icons.Filled.AddCircleOutline,
contentDescription = "Increase order button",
tint = Color(R.color.yellow_700)
)
}
}
ViewModel 方面看起来像这样:
private val _itemList = MutableLiveData<ArrayList<Item>>()
val itemList: LiveData<List<Item>>
get() = _itemList
fun increaseItemCount(id: String) {
val theList = _itemList.value
theList?.find { item ->
item.itemId == id
}?.let { item ->
item.itemQuantity += 1
_itemList.value = theList!!
}
}
decreaseItemCount 函数类似于 increaseItemCount,唯一的区别是计数在减少。
更新对象 属性 时,LiveData
无法知道该对象已更改。并且列表仍然包含相同的对象列表。
解决方案是实际创建一个具有更新属性的新对象。数据 class 对此非常有用:将您的属性声明为 val
并使用 copy
.
查看 Why is immutability important in functional programming?。
实时数据版本:
data class Item(val itemId: String, val itemQuantity: Int)
private val _itemList = MutableLiveData<List<Item>>()
val itemList: LiveData<List<Item>>
get() = _itemList
fun increaseItemCount(id: String) {
val theList = _itemList.value?.toMutableList() ?: return
val index = theList.indexOfFirst { it.itemId == id }
if (index == -1) return
theList[index] = theList[index].let {
it.copy(itemQuantity = it.itemQuantity + 1)
}
_itemList.value = theList
}
mutableStateListOf
版本更短更简洁:
data class Item(val itemId: String, val itemQuantity: Int)
private val _itemList = mutableStateListOf<Item>()
val itemList: List<Item> = _itemList
fun increaseItemCount(id: String) {
val index = _itemList.indexOfFirst { it.itemId == id }
if (index == -1) return
_itemList[index] = _itemList[index].let {
it.copy(itemQuantity = it.itemQuantity + 1)
}
}