如何更新列表状态以在 Compose 中显示更新

Dav*_*d A 5 android-jetpack-compose

我正在尝试创建一个可以动态更新的列表,它可能会更改几个或多个字段。的初始更新updateItems()很好,一切都按其应有的方式显示,但是 updateOneItem 的连续更新会被 Jetpack Compose 忽略。

// ****ViewModel code
val _itemList: MutableStateFlow<List<Item>> = MutableStateFlow(emptyList())

fun updateItems() {
    viewModelScope.launch {
        _itemList.value = itemRepository.getItems()
    }
}

fun updateOneItem(newVal:Int){
    _itemList.value[_itemList.value.indexOf(item)].weight = newVal
    //this is where I cannot have an update show up in compose no matter what
    _itemList.tryEmit(_itemList.value)
}
// ****continued ViewModel Code
Run Code Online (Sandbox Code Playgroud)

我一直在尝试复制列表,也尝试过mutableStateListOf,但到目前为止没有任何效果。

Phi*_*hov 16

Flow 无法知道包含对象的某些可变属性何时发生变化。当您尝试发出它时,它会检查对象的地址 - 它与原来的地址相同 - 并忽略该发出。

您可以通过创建列表的副本来强制执行此操作。

但最干净的方法是使用mutableStateListOf并使您的项目成为不可变的数据类,然后您可以通过创建副本轻松更新它。查看为什么不变性在函数式编程中很重要?

它可以看起来像这样:

data class Item(val weight: Int)

private val _itemList = mutableStateListOf<Item>()
val itemList: List<Item> = _itemList

fun updateItems() {
    viewModelScope.launch {
        _itemList.addAll(itemRepository.getItems())
    }
}

fun updateOneItem(newVal:Int){
    val index = _itemList.indexOf(item)
    _itemList[index] = _itemList[index].copy(weight = newVal)
}
Run Code Online (Sandbox Code Playgroud)

  • @DavidA 不,如果您检查 `mutableStateListOf` 实现,您会发现它是 `MutableList` 的子类并实现了 `StateObject` 接口。它不是“State&lt;List&lt;Item&gt;&gt;”,这就是为什么我们不使用列表的委托,没有“值”。界面仅显示“List”这一事实并不能阻止 Compose 对“StateObject”更改做出反应。 (4认同)
  • 如何在可组合状态下调用?我们可以通过collectAsStateWithLifecycle进行委托吗? (2认同)