Maniya Joe
Maniya Joe

Reputation: 801

How do I set border color for the checkbox using jetpack compose

I need to implement checkbox that looks like this

enter image description here

I have tried to explore all the aspects provided by compose to alter the checkbox as below

colors: CheckboxColors = CheckboxDefaults.colors()

I found some alternative solution here but

  1. It doesn't works for me
  2. I feel just to change the checkbox border color there shouldn't be so much work around right.

Note: checkmark color can be changed by using color field

colors = CheckboxDefaults.colors(checkmarkColor = Black)

Any help is appreciated

Upvotes: 7

Views: 8816

Answers (6)

heet kanabar
heet kanabar

Reputation: 300

I know I am late but it has vary simple answer.

Checkbox(
                checked = isChecked,
                onCheckedChange = {
                    //TODO
                },
                colors = CheckboxDefaults.colors(
                    checkedColor = SecondaryColor,
                    uncheckedColor = BorderColor,
                    checkmarkColor = BackgroundColor,
                )
            )

Notice that I have used BorderColor to give border color which is unchecked color of a cehckbox.

uncheckedColor = BorderColor

Upvotes: 0

Esteban López
Esteban López

Reputation: 622

If you are using Material3 you can replace OnSurfaceVariant in your theme or just wrap the CheckBox with the MaterialTheme composable

MaterialTheme(
    colorScheme = lightColorScheme(
        onSurfaceVariant = color //Your color here
    )
) {
    Checkbox(
        checked = isChecked,
        onCheckedChange = { checked ->
            isChecked = checked
        },
        colors = CheckboxDefaults.colors(),
    )
}

Upvotes: 0

Sebi
Sebi

Reputation: 145

Checkbox(checked = checked == true,
         onCheckedChange = { scope.launch { setValue(key, it) } },
         colors = CheckboxDefaults.colors(uncheckedColor = Color.Gray))

In my case I than have only a gray border if the checkbox is unchecked. Maybe it also works for you.

Upvotes: 1

ZaberZiv
ZaberZiv

Reputation: 75

There is default colors function CheckboxDefaults.colors(). You can change the specific color.

@Composable
fun myCheckBoxColors(): CheckboxColors {
    return CheckboxDefaults.colors(
        checkedColor = Color.red,
        uncheckedColor = Color.transparent
    )
}

Upvotes: 4

Chetan Ansel
Chetan Ansel

Reputation: 468

You can try the below code and customize the checkbox border using Box.

@Composable
fun CustomCheckBox(
checked: Boolean,
onCheckedChange: ((Boolean) -> Unit),
checkBoxSize: Dp = 60.dp,
checkBoxBorderWidth: Dp = 1.dp,
checkBoxBorderColorSelected: Int = R.color.black,
checkBoxBorderColorUnSelected: Int = R.color.teal_200,
checkBoxCheckedIconColor: Int = R.color.black,
) {
// state is used to hold the checkbox click or not by default is false
val checkBoxState = remember { mutableStateOf(checked) }
// Ui for checkbox
Box(
    modifier = Modifier
        .border(BorderStroke(checkBoxBorderWidth,
            if (checkBoxState.value) colorResource(id = checkBoxBorderColorSelected)
            else colorResource(id = checkBoxBorderColorUnSelected)))
        .size(checkBoxSize)
        .background(Color.Transparent)
        .clickable {
            onCheckedChange(!checkBoxState.value)
            checkBoxState.value = !checkBoxState.value
        },
    contentAlignment = Alignment.Center
) {
    if (checkBoxState.value)
        Icon(Icons.Default.Check,
            tint = colorResource(id = checkBoxCheckedIconColor),
            contentDescription = "Custom CheckBox")
}
}

Upvotes: 0

Jokubas Trinkunas
Jokubas Trinkunas

Reputation: 854

You need to implement CheckboxColors interface and create your color scheme. I just copied the implementation of DefaultCheckboxColors:

@Stable
class YourCheckboxColors(
    private val checkedCheckmarkColor: Color,
    private val uncheckedCheckmarkColor: Color,
    private val checkedBoxColor: Color,
    private val uncheckedBoxColor: Color,
    private val disabledCheckedBoxColor: Color,
    private val disabledUncheckedBoxColor: Color,
    private val disabledIndeterminateBoxColor: Color,
    private val checkedBorderColor: Color,
    private val uncheckedBorderColor: Color,
    private val disabledBorderColor: Color,
    private val disabledIndeterminateBorderColor: Color
) : CheckboxColors {

    private val BoxInDuration = 50
    private val BoxOutDuration = 100
    private val CheckAnimationDuration = 100

    private val CheckboxRippleRadius = 24.dp
    private val CheckboxDefaultPadding = 2.dp
    private val CheckboxSize = 20.dp
    private val StrokeWidth = 2.dp
    private val RadiusSize = 2.dp

    @Composable
    override fun checkmarkColor(state: ToggleableState): State<Color> {
        val target = if (state == ToggleableState.Off) {
            uncheckedCheckmarkColor
        } else {
            checkedCheckmarkColor
        }

        val duration = if (state == ToggleableState.Off) BoxOutDuration else BoxInDuration
        return animateColorAsState(target, tween(durationMillis = duration))
    }

    @Composable
    override fun boxColor(enabled: Boolean, state: ToggleableState): State<Color> {
        val target = if (enabled) {
            when (state) {
                ToggleableState.On, ToggleableState.Indeterminate -> checkedBoxColor
                ToggleableState.Off -> uncheckedBoxColor
            }
        } else {
            when (state) {
                ToggleableState.On -> disabledCheckedBoxColor
                ToggleableState.Indeterminate -> disabledIndeterminateBoxColor
                ToggleableState.Off -> disabledUncheckedBoxColor
            }
        }

        // If not enabled 'snap' to the disabled state, as there should be no animations between
        // enabled / disabled.
        return if (enabled) {
            val duration = if (state == ToggleableState.Off) BoxOutDuration else BoxInDuration
            animateColorAsState(target, tween(durationMillis = duration))
        } else {
            rememberUpdatedState(target)
        }
    }

    @Composable
    override fun borderColor(enabled: Boolean, state: ToggleableState): State<Color> {
        val target = if (enabled) {
            when (state) {
                ToggleableState.On, ToggleableState.Indeterminate -> checkedBorderColor
                ToggleableState.Off -> uncheckedBorderColor
            }
        } else {
            when (state) {
                ToggleableState.Indeterminate -> disabledIndeterminateBorderColor
                ToggleableState.On, ToggleableState.Off -> disabledBorderColor
            }
        }

        // If not enabled 'snap' to the disabled state, as there should be no animations between
        // enabled / disabled.
        return if (enabled) {
            val duration = if (state == ToggleableState.Off) BoxOutDuration else BoxInDuration
            animateColorAsState(target, tween(durationMillis = duration))
        } else {
            rememberUpdatedState(target)
        }
    }
}

And then you can set the colors by simply:

        Checkbox(
            colors = YourCheckboxColors(
                checkedBorderColor = Ink900,
                checkedBoxColor = Light,
                checkedCheckmarkColor = Ink900,
                uncheckedCheckmarkColor = Ink900.copy(alpha = 0f),
                uncheckedBoxColor = Light.copy(alpha = 0f),
                disabledCheckedBoxColor = Light,
                disabledUncheckedBoxColor = Light.copy(alpha = 0f),
                disabledIndeterminateBoxColor = Light,
                uncheckedBorderColor = Ink900,
                disabledBorderColor = Ink900,
                disabledIndeterminateBorderColor = Ink900,
            ),
            onCheckedChange = {}
        )

Upvotes: 6

Related Questions