Jetpack Compose 中复选框的嵌套状态

Nested State for checkbox in jetpack compose

我遇到了与 Jetpack Compose 中的状态相关的问题。问题是我有包含问题的列表。有些问题需要单选按钮,有些问题需要多选复选框。见下图..

Screen shot example.

Raio Buttino 代码

查看模型class

private val _isRadioChecked = mutableStateListOf<ResearchQuestion>()
val optionState: List<ResearchQuestion> = _isRadioChecked

fun setRadioChecked(index: Int,isChecked: ResearchQuestion) {
    _isRadioChecked[index] = isChecked
}
fun setRadioChecked(isChecked: ResearchQuestion) {
    _optionState.add(isChecked)
}

数据class -> ResearchQuestion

val question: String = "",
val isMultipleChoice: Boolean = false,
val selectedMultipleOption: Set<Int> = emptySet(),
val selectOption: Int = -1,

撰写屏幕 -> 单选按钮撰写

@Composable
fun CodeRadioButton(
  options: List<String>,
  selectedOption: Int,
  onOptionSelected: (Int) -> Unit
) {
  options.forEachIndexed { index, option ->
    Row(
        modifier = Modifier
            .padding(vertical = 5.dp),
        verticalAlignment = Alignment.CenterVertically,
    ) {
        RadioButton(
            modifier = Modifier
                .size(15.dp)
                .padding(start = 15.dp),
            selected = (index == selectedOption),
            onClick = {
                onOptionSelected(index)
            }
        )
        Spacer(modifier = Modifier.padding(horizontal = 15.dp))
        Text(
            modifier = Modifier
                .clickable {
                    onOptionSelected(index)
                },
            text = option,
            style = MaterialTheme.typography.body2
        )
        Spacer(modifier = Modifier.padding(vertical = 10.dp))
    }
  }
 }

撰写屏幕 -> 复选框按钮组成

@Composable
fun CodeMultipleChoice(
  options: List<String>,
  isMultipleChecked: Set<Int>,
  onMultiOptionSelected: (List<Int>) -> Unit,
) {

  options.forEachIndexed { index, option ->
    Row(
        modifier = Modifier
            .padding(vertical = 5.dp),
        verticalAlignment = Alignment.CenterVertically,
    ) {
        Checkbox(
            modifier = Modifier
                .size(15.dp)
                .padding(start = 15.dp),
            checked = false, //State did not work
            onCheckedChange = {
                //State did not work
            },
            colors = CheckboxDefaults.colors(
                checkmarkColor = Color.White
            )
        )
        Spacer(modifier = Modifier.padding(horizontal = 15.dp))
        Text(
            modifier = Modifier
                .clickable {
                    
                },
            text = option,
            style = MaterialTheme.typography.body2
        )
        Spacer(modifier = Modifier.padding(vertical = 10.dp))
    }
  }
}

注意:单选按钮工作正常,但多选(复选框)状态不起作用。 我创建了 mutableStateList0f() 但如果选中复选框,其他有多个问题的问题也会发生变化。

我将更改的行标记为'changed line'

@Composable
fun CodeMultipleChoice(
    options: List<String>,
    isMultipleChecked: Set<Int>,
    onMultiOptionSelected: (List<Int>) -> Unit,
) {

    var multipleChecked by remember { mutableStateOf(isMultipleChecked)}//*Changed line

    options.forEachIndexed { index, option ->
        Row(
            modifier = Modifier
                .padding(vertical = 5.dp),
            verticalAlignment = Alignment.CenterVertically,
        ) {
            Checkbox(
                modifier = Modifier
                    .size(15.dp)
                    .padding(start = 15.dp),
                checked = multipleChecked.contains(index), //*Changed line
                onCheckedChange = { //*Changed line
                    if(it){
                        multipleChecked = multipleChecked + index
                    } else{
                        multipleChecked = multipleChecked - index
                    }
                },
                colors = CheckboxDefaults.colors(
                    checkmarkColor = Color.White
                )
            )
            Spacer(modifier = Modifier.padding(horizontal = 15.dp))
            Text(
                modifier = Modifier
                    .clickable {

                    },
                text = option,
                style = MaterialTheme.typography.body2
            )
            Spacer(modifier = Modifier.padding(vertical = 10.dp))
        }
    }
}