在我导航出去之前,LiveData 值不会更新 Jetpack Compose 中的 UI

发布于 2025-01-16 20:39:23 字数 1951 浏览 6 评论 0原文

我正在从可组合项调用 increaseCount(id: String) 方法来增加 LiveData 对象列表中的参数值。该值更新得很好,但用户界面仅在我导航出去后才显示更新。 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 ,唯一的区别是计数正在减少。

I am calling an increaseCount(id: String) method from a composable to increase the value of a parameter in a LiveData List of objects. The value gets updated quite alright but the UI only shows the update once I navigate out. PS: I am using a BottomNavigation view for navigating.

The Composable screen in question looks something like this

@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)
                )
            }
        }

The ViewModel side of things looks something like this:

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!!
    }
}

The decreaseItemCount function is similar to the increaseItemCount with the only difference being the count is decreasing.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

没有你我更好 2025-01-23 20:39:24

当您更新对象属性时,LiveData 无法知道该对象已更改。并且列表仍然包含相同的对象列表。

解决方案是实际创建一个具有更新属性的新对象。数据类对此非常满意:将属性声明为 val 并使用 copy 更新它们。

查看为什么不变性在函数式编程中很重要?

实时数据版本:

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)
    }
}

When you update an object property, LiveData cannot know that this object has changed. And a list still contains the same list of objects.

The solution is to actually create a new object with updated properties. data class is very comfy for this: declare your properties as val and update them using copy.

Check out Why is immutability important in functional programming?.

Live data version:

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 version is a little bit shorted and cleaner:

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)
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文