当前位置: 首页 > 知识库问答 >
问题:

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

仉昱
2023-03-14

我正在从可组合对象调用增量计数(id: String)方法以增加LiveData对象列表中参数的值。该值更新得很好,但UI仅在我导航出去后显示更新。PS:我正在使用BottomNaviation视图进行导航。

问题中的可组合屏幕看起来像这样

@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,唯一的区别是计数在减少。

共有1个答案

琴英华
2023-03-14

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

解决方案是实际创建一个具有更新属性的新对象。数据类对此非常方便:将属性声明为< code>val并使用< code>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)
    }
}
 类似资料:
  • 在我的片段中,我观察到db问卷列表字段: 在我的片段中,我有几个按钮,根据哪个按钮被按下,我在viewModel上调用方法,将设置为标签的字符串传递给按钮。 我的视图模式: 存储库方法: Dao方法: 当我按下按钮时,viewModel方法被调用,并带有参数,该参数应该用于通过搜索房间数据库来更新LiveData,但没有任何内容会被无缘无故地更新。数据库不是空的,所以没有理由在主片段中返回null

  • 我目前正在重构遗留代码,以使用Android架构组件,并在一种存储库模式中设置一个房间数据库和截取请求。因此,表示层/域层要求存储库获取LiveData对象进行观察,或告诉他与服务器同步,然后删除旧的db条目,并从服务器中重新提取所有当前条目。 我已经写了同步部分的测试,所以我确信,对象被正确地获取并插入到数据库中。但是当写一个测试来观察db表的条目时(并测试对象是否被正确保存,以及在将它们放入d

  • UserViewModel: 用户存储库:

  • 我已使用此(react router 2.0)在路由器上设置了browserHistory: 然后,我尝试使用react router中的browserHistory以编程方式从视图(ala: 这将URL更改为 /map但不会呈现该路由中的组件。我做错了什么?

  • 问题内容: 我正在使用GUI和JFrames / JPanels创建棋盘游戏,您可以在计算机上玩该游戏。我有一个名为showPieces()的方法,该方法通过更改按钮数组(以网格格式布置)上的图像图标来更新板子GUI。一旦图标已更新,则和方法将更新GUI。showPieces()方法具有一个参数,每次调用它时都需要将其传递给它。 我遇到的主要问题是,我希望人类采取行动,更新GUI,等待1秒钟,计算

  • 我试图改变菜单的外观,将链接移动到与社交媒体图标和主页按钮相同的行上。 链接在主navbar类(Streetwear-Demos)下的div中,社交媒体图标和主页也在自己的div中浮动到他们尊敬的一边。我试着改变navbar类的宽度,以为它会加入,但它只是改变了链接的定位。 我如何使它使每个社交媒体的链接和图标在同一条线上,居中? null null 任何帮助都将不胜感激!