Jetpack Compose 复选框未显示更改状态

muc*_*gan 4 android android-checkbox android-jetpack-compose

我有一个用户可以检查的专业列表。当用户对他们的选择感到满意后,我将收集所选复选框的信息并将这些专业保存在用户的个人资料中。

但是,当我点击任何复选框时,视图模型中的状态会发生变化,但复选框仍处于未选中状态。

专业列表

@Composable
fun SpecialtyList(
    viewModel: SpecialtyListViewModel = hiltViewModel(),
    navController: NavController
) {
    LazyColumn(modifier = Modifier.fillMaxSize()) {
        item {
            viewModel.specialtyList.value.forEach { specialty ->
                Row(
                    modifier = Modifier
                        .fillMaxWidth()
                        .padding(10.dp),
                    verticalAlignment = Alignment.CenterVertically
                ) {
                    Checkbox(
                        checked = specialty.isSelected,
                        onCheckedChange = {
                            specialty.isSelected = it
                        },
                        colors = CheckboxDefaults.colors(MaterialTheme.colors.primary)
                )
                    Text(
                        text = specialty.name,
                        modifier = Modifier
                            .padding(horizontal = 10.dp)
                    )
                }
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

专业视图模型

@HiltViewModel
class SpecialtyListViewModel @Inject constructor() : ViewModel() {

    // HARD-CODED PROPERTIES
    val specialtyList = mutableStateOf(
        mutableListOf(
            Specialty(name = "Emergency Medicine", isSelected = false),
            Specialty(name = "Forensic Medicine", isSelected = false),
            Specialty(name = "General Practitioner", isSelected = false)
    )
}
Run Code Online (Sandbox Code Playgroud)

专业型号

data class Specialty(
    val name: String,
    var isSelected: Boolean
)
Run Code Online (Sandbox Code Playgroud)

Phi*_*hov 6

为了mutableStateOf触发重组,应该更新容器值,例如specialtyList = newValue

它无法知道您已经更改了内部对象之一。

一般来说,data class不可变是函数式编程中使用的一个很好的工具。如果您不在var其中使用,您将排除许多错误。

mutableStateListOf如果您的情况看起来更干净,请使用。在您的视图模型中:

private val _specialtyList = mutableStateListOf(
    Specialty(name = "Emergency Medicine", isSelected = false),
    Specialty(name = "Forensic Medicine", isSelected = false),
    Specialty(name = "General Practitioner", isSelected = false)
)
val specialtyList: List<Specialty> = _specialtyList

fun setSpecialtySelectedAtIndex(index: Int, isSelected: Boolean) {
    _specialtyList[index] = _specialtyList[index].copy(isSelected = isSelected)
}
Run Code Online (Sandbox Code Playgroud)

从您的可组合项中使用它,如下所示:

viewModel.specialtyList.value.forEachIndexed { i, specialty ->
    // ...
    onCheckedChange = {
        viewModel.setSpecialtySelectedAtIndex(i, it)
    },
}
Run Code Online (Sandbox Code Playgroud)

您可以在文档中找到有关 Compose 状态的更多信息,包括这个解释基本原理的YouTube 视频。