Home > Software design >  How can I select only ONE checkbox (jetpack compose/kotlin)?
How can I select only ONE checkbox (jetpack compose/kotlin)?

Time:09-06

I have a list of options and each of them has a checkbox. I want the user to be able to select only one. Chechkbox:

@Composable
fun CheckboxResource(isSelected: Boolean): Painter {
    return if (isSelected) {
        painterResource(id = R.drawable.check_on)
    } else {
        painterResource(id = R.drawable.check_off)
    }
}

And the Composable:

fun SelectOptionsCheckbox(
    isSelectedOption: Boolean,
    onSelectOption: (Boolean) -> Unit
) {

        val selectedOption = remember {
            mutableStateOf(isSelectedOption)
        }
 Row {
   Text()
            Icon(
                painter = CheckboxResource(isSelected = selectedOption.value),
                contentDescription = "Checkbox",
                modifier = Modifier
                    .clickable {
                        selectedOption.value = selectedOption.value.not()
                        onSelectOption(selectedOption.value)
                    },
)}

In this way the checkbox works but I can select all the options

CodePudding user response:

I updated to imageVector because i don't have drawables you can use yours

@Composable
fun CheckboxResource(isSelected: Boolean): ImageVector {
    return if (isSelected) {
        Icons.Default.Check
    } else {
        Icons.Default.Cancel
    }
}

@Composable
fun SelectOptionsCheckout(
    text: String,
    isSelectedOption: Boolean,
    onSelectOption: (String) -> Unit
) {

    Row {
        Text(text)
        Icon(
            imageVector = CheckboxResource(isSelected = isSelectedOption),
            contentDescription = "Checkbox",
            modifier = Modifier
                .clickable {
                    onSelectOption(text)
                },
        )
    }
}

Checkbox group

   @Composable
    private fun CheckBoxGroup() {
        val radioOptions = listOf("OptionA", "OptionB", "OptionC")
    
        val (selectedOption: String, onOptionSelected: (String) -> Unit) = remember {
            mutableStateOf(
                radioOptions[0]
            )
        }
    
        Column(Modifier.selectableGroup()) {
            radioOptions.forEach { text ->
                SelectOptionsCheckout(
                    text = text,
                    isSelectedOption = selectedOption == text,
                    onSelectOption = onOptionSelected
                )
            }
        }
    }

Checkbox Group with no initial selected item

Change state from Int to String and pass index of checkBox and return these on click and compare them previous one. If it's equal to previous one set new one as -1

@Composable
fun SelectOptionsCheckout(
    index: Int,
    text: String,
    isSelectedOption: Boolean,
    onSelectOption: (Int) -> Unit
) {

    Row() {
        Text(text)
        Icon(
            imageVector = CheckboxResource(isSelected = isSelectedOption),
            contentDescription = "Checkbox",
            modifier = Modifier
                .clickable {
                    onSelectOption(index)
                }
        )
    }
}

@Composable
private fun CheckBoxGroup() {
    val radioOptions = listOf("OptionA", "OptionB", "OptionC")

    val (selectedOption: Int, onOptionSelected: (Int) -> Unit) = remember {
        mutableStateOf(
            -1
        )
    }

    Column(Modifier.selectableGroup()) {
        radioOptions.forEachIndexed { index, text ->
            SelectOptionsCheckout(
                index = index,
                text = text,
                isSelectedOption = selectedOption == index,
                onSelectOption = {
                    if (it == selectedOption) {
                        onOptionSelected(-1)
                    } else {
                        onOptionSelected(it)
                    }
                }
            )
        }
    }
}
  • Related