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

Viewed 833

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

1 Answers

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 = {}
        )
Related