在我导航出去之前,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)
    }
}