简体   繁体   English

使用 List as State 时,如何在 Jetpack Compose 中的 item`attribute 更改时更新 UI?

[英]When using List as State, how to update UI when item`attribute change in Jetpack Compose?

For example, I load data into a List, it`s wrapped by MutableStateFlow, and I collect these as State in UI Component.例如,我将数据加载到一个列表中,它由 MutableStateFlow 包装,我在 UI 组件中将这些收集为 State。

The trouble is, when I change an item in the MutableStateFlow<List>, such as modifying attribute, but don`t add or delete, the UI will not change.麻烦的是,当我更改 MutableStateFlow<List> 中的项目时,例如修改属性,但不添加或删除,UI 不会改变。

So how can I change the UI when I modify an item of the MutableStateFlow?那么,当我修改 MutableStateFlow 的一项时,如何更改 UI?

These are codes:这些是代码:

ViewModel:视图模型:

data class TestBean(val id: Int, var name: String)
class VM: ViewModel() {
    val testList = MutableStateFlow<List<TestBean>>(emptyList())

    fun createTestData() {
        val result = mutableListOf<TestBean>()
        (0 .. 10).forEach {
            result.add(TestBean(it, it.toString()))
        }
        testList.value = result
    }

    fun changeTestData(index: Int) {

        // first way to change data
        testList.value[index].name = System.currentTimeMillis().toString()

        // second way to change data
        val p = testList.value[index]
        p.name = System.currentTimeMillis().toString()
        val tmplist = testList.value.toMutableList()
        tmplist[index].name = p.name
        testList.update { tmplist }
}

} }

UI:用户界面:

    setContent {
        LaunchedEffect(key1 = Unit) {
            vm.createTestData()
        }
        Column {
            vm.testList.collectAsState().value.forEachIndexed { index, it ->
                Text(text = it.name, modifier = Modifier.padding(16.dp).clickable {
                    vm.changeTestData(index)
                    Log.d("TAG", "click: ${index}")
                })
            }
        }
    }

Both Flow and Compose mutable state cannot track changes made inside of containing objects. Flow和 Compose 可变 state 都无法跟踪包含对象内部所做的更改。

But you can replace an object with an updated object. data class is a nice tool to be used, which will provide you all copy out of the box, but you should emit using var and only use val for your fields to avoid mistakes.但是你可以用更新的 object 替换 object。 data class是一个很好用的工具,它会为你提供开箱即用的所有copy ,但你应该使用var发出并且只对你的字段使用val以避免错误。

Check out Why is immutability important in functional programming?查看为什么不变性在函数式编程中很重要?

testList.value[index] = testList.value[index].copy(name = System.currentTimeMillis().toString())

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 当 viewModel 中的状态发生变化时,Jetpack compose Lazy Column 项目状态不会改变 - Jetpack compose Lazy Column item state does not change when state in viewModel changes Jetpack Compose:列表更改时更新可组合 - Jetpack Compose: Update composable when list changes 在 Jetpack Compose 中单击时更改表面项目的背景颜色 - Change background color of surface item when click in jetpack compose 在 Android Jetpack Compose 中使用 State 时出现 java.lang.IllegalStateException - java.lang.IllegalStateException when using State in Android Jetpack Compose 使用 Compose UI 时如何为每个列表项创建单独的 ViewModel? - How to create separate ViewModels per list item when using Compose UI? 使用 android Jetpack compose 中的列表处理 state - Handling state using list in android Jetpack compose 使用 LazyRow 或 Column 时如何使项目出现在屏幕中央 Jetpack Compose? - How to make item appear in the center of the screen Jetpack Compose when using LazyRow or Column? Jetpack Compose - LazyColumnFor 在添加项目时不重新组合 - Jetpack Compose - LazyColumnFor not recomposing when item added 如何检查 Jetpack Compose 中列表项的可见性 - How to check visibility of list item in Jetpack Compose 当列表项属性发生变化时,Livedata 不更新 compose state - Livedata don't update compose state when list item property has changed
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM