compose LazyColumn + items没有自动刷新问题

val dataLists by remember { mutableStateOf(datas) } 数据更改后列表不刷新问题。

val dataLists by remember {  mutableStateOf(datas) } 

LazyColumn(modifier = Modifier.padding(top = 5.dp)) {
                items(dataLists) {
                    ....
                }
            }

可以将mutableStateOf 改为mutableStateListOf解决问题:

val dataLists = remember {
    mutableStateListOf()
}
dataLists.addAll(datas)

追溯问题原因:

查询源码可以发现:mutableStateOf()返回的是一个MutableState对象,MutableState中有一个var value: T属性

@StateFactoryMarker
fun  mutableStateOf(
    value: T,
    policy: SnapshotMutationPolicy = structuralEqualityPolicy()
): MutableState = createSnapshotMutableState(value, policy)

@Stable
interface State {
    val value: T
}

...

@Stable
interface MutableState : State {
    override var value: T
    operator fun component1(): T
    operator fun component2(): (T) -> Unit
}

查看mutableStateOf源码,可以发现,mutableStateOf()返回的是继承自MutableState的SnapshotMutableState对象,路径mutableStateOf()-> createSnapshotMutableState() -> ParcelableSnapshotMutableState-> SnapshotMutableStateImpl,可以看到有这样一段代码:

internal open class SnapshotMutableStateImpl(
    value: T,
    override val policy: SnapshotMutationPolicy
) : StateObjectImpl(), SnapshotMutableState {
    @Suppress("UNCHECKED_CAST")
    override var value: T
        get() = next.readable(this).value
        set(value) = next.withCurrent {
            if (!policy.equivalent(it.value, value)) {
                next.overwritable(this, it) { this.value = value }
            }
        }

    private var next: StateStateRecord = StateStateRecord(value)
    ......

SnapshotMutableStateImpl的value属性重写了get()和set()方法

当value被读的时候,不光把值返回,还会记录一下在哪被读的当value被写的时候,不止把这个值给改了,还会去查找在哪里被读过,然后通知这些被读过的地方,通知UI进行刷新

操作String、Int等基础类型的时候,都是通过get、set()来获取、设置数据的,所以这操作会被SnapshotMutableStateImpl记录下来,而List、Map这种集合,我们是通过add、remove来更新数据的,所以不会触发SnapshotMutableStateImpl value属性的set。

结论: 使用mutableStateListOf替代mutableStateOf,mutableStateListOf内部对add、remove方法也进行了重写:

val dataLists = remember {
    mutableStateListOf()
}
dataLists.addAll(datas)

dataLists数据更改时,UI回自动刷新。

你可能感兴趣的:(compose,android,compose)