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<Message>()
}
dataLists.addAll(datas)
追溯问题原因:
查询源码可以发现:mutableStateOf()返回的是一个MutableState对象,MutableState中有一个var value: T属性
@StateFactoryMarker
fun <T> mutableStateOf(
value: T,
policy: SnapshotMutationPolicy<T> = structuralEqualityPolicy()
): MutableState<T> = createSnapshotMutableState(value, policy)
@Stable
interface State<out T> {
val value: T
}
...
@Stable
interface MutableState<T> : State<T> {
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<T>(
value: T,
override val policy: SnapshotMutationPolicy<T>
) : StateObjectImpl(), SnapshotMutableState<T> {
@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<T> = 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<T>()
}
dataLists.addAll(datas)
dataLists数据更改时,UI回自动刷新。