0

我有一个项目列表,每个项目都有一个复选框。复选框的状态需要存储在 中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

                            }
                        )
                    }
                )
            }
        }
    }
}

我试图item.selected通过更新回调中的列表(MutableLiveData<List<Object>>in viewmodel)来更新onCheckedChange,但 UI 没有更新。如果我向下滚动然后向上滚动 UI 更新并且复选框似乎被选中。为什么不更新?

4

1 回答 1

2

MutableLiveData对它持有的对象一无所知。当某些内部对象属性更新时,它无法向您发送新值。

要使用实时数据解决此问题,您需要为您的项目设置新值,设置相同的值就足够了:

fun setSelected(index: Int, selected: Boolean) {
    items.value!![index].selected = selected
    items.value = items.value
}

但是如果你没有LiveData被其他依赖绑定,我建议你不要使用它。mutableStateListOf与 immutable 一起使用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)
        }
    // ...
    }
}
于 2021-11-23T01:35:29.293 回答