Android 实时数据更改时,Compose lazycolumn 不会更新
Android Compose lazycolumn does not update when livedata is changed
我有一个项目列表,每个项目都有一个复选框。复选框的状态需要存储在 viewmodel
中,最好 viewmodel
中的列表应该是唯一的真实来源。
@Composable
fun Screen(viewModel: ViewModel) {
val list by viewModel.items.observeAsState()
LazyColumn {
list?.let { items ->
items(items) { item ->
ListItem(
text = {
Text(item.name)
},
secondaryText = {
Text(item.phoneNumber)
},
icon = {
Checkbox(
modifier = Modifier.padding(8.dp),
checked = item.selected,
onCheckedChange = {
//TODO
}
)
}
)
}
}
}
}
我试图通过在 onCheckedChange
回调中更新列表(viewmodel
中的 MutableLiveData<List<Object>>
)来更新 item.selected
,但是 UI不更新。如果我向下滚动然后向上滚动 UI 更新并且复选框似乎被选中。为什么不更新?
MutableLiveData
对其持有的对象一无所知。当某些内部对象 属性 更新时,它无法向您发送新值。
要使用实时数据解决此问题,您需要为项目设置新值,设置相同的值就足够了:
fun setSelected(index: Int, selected: Boolean) {
items.value!![index].selected = selected
items.value = items.value
}
但是如果你没有被其他依赖绑定到LiveData
,我建议你不要使用它。将 mutableStateListOf
与不可变的 data class
一起使用会更简洁:
data class Object(val selected: Boolean)
class VM: ViewModel() {
val items = mutableStateListOf<Object>()
fun setSelected(index: Int, selected: Boolean) {
items[index] = items[index].copy(selected = selected)
}
}
在这两种情况下,您都需要对象索引,您可以通过 itemsIndexed
:
获取它
val list = viewModel.items
LazyColumn {
itemsIndexed(list) { index, item ->
// ...
onCheckedChange = {
viewModel.setSelected(index, it)
}
// ...
}
}
我有一个项目列表,每个项目都有一个复选框。复选框的状态需要存储在 viewmodel
中,最好 viewmodel
中的列表应该是唯一的真实来源。
@Composable
fun Screen(viewModel: ViewModel) {
val list by viewModel.items.observeAsState()
LazyColumn {
list?.let { items ->
items(items) { item ->
ListItem(
text = {
Text(item.name)
},
secondaryText = {
Text(item.phoneNumber)
},
icon = {
Checkbox(
modifier = Modifier.padding(8.dp),
checked = item.selected,
onCheckedChange = {
//TODO
}
)
}
)
}
}
}
}
我试图通过在 onCheckedChange
回调中更新列表(viewmodel
中的 MutableLiveData<List<Object>>
)来更新 item.selected
,但是 UI不更新。如果我向下滚动然后向上滚动 UI 更新并且复选框似乎被选中。为什么不更新?
MutableLiveData
对其持有的对象一无所知。当某些内部对象 属性 更新时,它无法向您发送新值。
要使用实时数据解决此问题,您需要为项目设置新值,设置相同的值就足够了:
fun setSelected(index: Int, selected: Boolean) {
items.value!![index].selected = selected
items.value = items.value
}
但是如果你没有被其他依赖绑定到LiveData
,我建议你不要使用它。将 mutableStateListOf
与不可变的 data class
一起使用会更简洁:
data class Object(val selected: Boolean)
class VM: ViewModel() {
val items = mutableStateListOf<Object>()
fun setSelected(index: Int, selected: Boolean) {
items[index] = items[index].copy(selected = selected)
}
}
在这两种情况下,您都需要对象索引,您可以通过 itemsIndexed
:
val list = viewModel.items
LazyColumn {
itemsIndexed(list) { index, item ->
// ...
onCheckedChange = {
viewModel.setSelected(index, it)
}
// ...
}
}