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)
        }
    // ...
    }
}