我可以使用 State<ArrayList<T>> 或 State<mutableListOf()> 来让 Compose 观察到它们发生变化时触发重组吗?

Hel*_*oCW 3 kotlin android-jetpack-compose

以下内容摘自文章

1:我不完全明白我是否可以使用State<ArrayList<T>>State<mutableListOf()>由 Compose 观察以在它们发生变化时触发重组?

2:我很奇怪为什么State<List<T>>和 immutablelistOf()可以通过 Compose 观察到它们发生变化时触发重组,但实际上List<T>和 immutablelistOf()是不可变的,你能给我一些示例代码吗?

注意:在 Compose 中使用可变对象(例如 ArrayList 或 mutableListOf())作为状态将导致用户在应用程序中看到不正确或过时的数据。

不可观察的可变对象(例如 ArrayList 或可变数据类)无法被 Compose 观察到,从而在它们发生更改时触发重组。

我们建议您使用可观察的数据持有者,例如 State<List> 和不可变的 listOf(),而不是使用不可观察的可变对象。

图像 在此输入图像描述

Abh*_*bhi 7

核心理念是

仅当发生可观察的状态变化时才会发生重组。

对于可变对象,我们可以选择使用add(),remove()等方法并直接修改对象。
但这种变化不会触发重组,因为这种变化是不可观察的。(对象实例没有改变)

即使对于可变对象,我们也可以通过将它们分配给新的对象实例来触发适当的重组。(对象实例发生改变)

因此,使用可变对象很容易出错。

我们还可以看到由于此问题而导致的 lint 错误。

在此输入图像描述

另一方面,list不可修改的不可变对象。它们被替换为新的对象实例。
因此它们是可观察的并且会发生适当的重组。(对象实例发生改变)

以此为例来理解这个概念。

@Composable
fun ComposeListExample() {
    var mutableList: MutableState<MutableList<String>> = remember {
        mutableStateOf(mutableListOf())
    }
    var mutableList1: MutableState<MutableList<String>> = remember {
        mutableStateOf(mutableListOf())
    }
    var arrayList: MutableState<ArrayList<String>> = remember {
        mutableStateOf(ArrayList())
    }
    var arrayList1: MutableState<ArrayList<String>> = remember {
        mutableStateOf(ArrayList())
    }
    var list: MutableState<List<String>> = remember {
        mutableStateOf(listOf())
    }
    
    Column(
        Modifier.verticalScroll(state = rememberScrollState())
    ) {
        // Uncomment the below 5 methods one by one to understand how they work.
        // Don't uncomment multiple methods and check.
        
        
        // ShowListItems("MutableList", mutableList.value)
        // ShowListItems("Working MutableList", mutableList1.value)
        // ShowListItems("ArrayList", arrayList.value)
        // ShowListItems("Working ArrayList", arrayList1.value)
        // ShowListItems("List", list.value)

        Button(
            onClick = {
                mutableList.value.add("")
                arrayList.value.add("")

                val newMutableList1 = mutableListOf<String>()
                mutableList1.value.forEach {
                    newMutableList1.add(it)
                }
                newMutableList1.add("")
                mutableList1.value = newMutableList1

                val newArrayList1 = arrayListOf<String>()
                arrayList1.value.forEach {
                    newArrayList1.add(it)
                }
                newArrayList1.add("")
                arrayList1.value = newArrayList1

                val newList = mutableListOf<String>()
                list.value.forEach {
                    newList.add(it)
                }
                newList.add("")
                list.value = newList
            },
        ) {
            Text(text = "Add")
        }
    }
}

@Composable
private fun ShowListItems(title: String, list: List<String>) {
    Text(title)
    Column {
        repeat(list.size) {
            Text("$title Item Added")
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

PS:mutableStateListOf如果您有需要修改的项目列表并正确触发重组,请使用。