개발 공부/안드로이드

[Compose] 컴포즈 공부하기 8 - CheckBox

yong_DD 2023. 9. 13. 17:55

Checkbox.kt에 들어가면 Checkbox와 TristateCheckbox가 있다.

@Composable
fun Checkbox(
    checked: Boolean,
    onCheckedChange: ((Boolean) -> Unit)?,
    modifier: Modifier = Modifier,
    enabled: Boolean = true,
    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
    colors: CheckboxColors = CheckboxDefaults.colors()
) {
    TriStateCheckbox(
        state = ToggleableState(checked),
        onClick = if (onCheckedChange != null) { { onCheckedChange(!checked) } } else null,
        interactionSource = interactionSource,
        enabled = enabled,
        colors = colors,
        modifier = modifier
    )
}

@Composable
fun TriStateCheckbox(
    state: ToggleableState,
    onClick: (() -> Unit)?,
    modifier: Modifier = Modifier,
    enabled: Boolean = true,
    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
    colors: CheckboxColors = CheckboxDefaults.colors()
) {
    val toggleableModifier =
        if (onClick != null) {
            Modifier.triStateToggleable(
                state = state,
                onClick = onClick,
                enabled = enabled,
                role = Role.Checkbox,
                interactionSource = interactionSource,
                indication = rememberRipple(
                    bounded = false,
                    radius = CheckboxRippleRadius
                )
            )
        } else {
            Modifier
        }
    CheckboxImpl(
        enabled = enabled,
        value = state,
        modifier = modifier
            .then(if (onClick != null) { Modifier.minimumTouchTargetSize() } else { Modifier })
            .then(toggleableModifier)
            .padding(CheckboxDefaultPadding),
        colors = colors
    )
}

코드를 보면 알겠지만 TriStateCheckbox는 Checkbox의 부모라는 것을 알 수 있다.

TriStateCheckbox를 직접 구현해서 사용할 수도 있지만 기본적인  기능의 Checkbox가 필요하다면 Checkbox만 사용해도 되기 때문에 이번에는 Checkbox만 알아보고 TriStateCheckbox를 통해 Checkbox가 동작하는 구나 정도만 알고 있어도 될 것 같다 😉

 

 

modifier를 제외한 체크박스 파라미터에 대해 하나씩 알아보면서 기본 동작을 구현해보자!

fun Checkbox(
    checked: Boolean,
    onCheckedChange: ((Boolean) -> Unit)?,
    modifier: Modifier = Modifier,
    enabled: Boolean = true,
    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
    colors: CheckboxColors = CheckboxDefaults.colors()
)

 

1. checked, onCheckedChange

다들 잘 알고 있겠지만, checked는 단어 그대로 체크박스가 체크가 되어있는지 아닌지에 대한 여부이다.

onCheckedChange도 당연히 변경된 값을 Boolean의 형태로 받게 된다.

 

        val checked by remember { mutableStateOf(false) }
        Checkbox(
            checked = checked,
            onCheckedChange = {
            	checked = !checked
            }
        )

 

기본적인 형태로 위 코드를 돌려보게 되면 다음과 같이 나오게 된다.

checked를 변경해줘야만 상태가 바뀌기 때문에 checked 값을 remember로 기억시켜주고,

체크박스가 눌리면 onCheckedChange가 불리기 때문에 checked의  값을 반대로 넣어주게 했다.

 

 

2. enabled, colors

interface CheckboxColors {

    @Composable
    fun checkmarkColor(state: ToggleableState): State<Color>

    @Composable
    fun boxColor(enabled: Boolean, state: ToggleableState): State<Color>
    
    @Composable
    fun borderColor(enabled: Boolean, state: ToggleableState): State<Color>
}

object CheckboxDefaults {

    @Composable
    fun colors(
        checkedColor: Color = MaterialTheme.colors.secondary,
        uncheckedColor: Color = MaterialTheme.colors.onSurface.copy(alpha = 0.6f),
        checkmarkColor: Color = MaterialTheme.colors.surface,
        disabledColor: Color = MaterialTheme.colors.onSurface.copy(alpha = ContentAlpha.disabled),
        disabledIndeterminateColor: Color = checkedColor.copy(alpha = ContentAlpha.disabled)
    ): CheckboxColors {
        return remember(
            checkedColor,
            uncheckedColor,
            checkmarkColor,
            disabledColor,
            disabledIndeterminateColor,
        ) {
            DefaultCheckboxColors(
                checkedBorderColor = checkedColor,
                checkedBoxColor = checkedColor,
                checkedCheckmarkColor = checkmarkColor,
                uncheckedCheckmarkColor = checkmarkColor.copy(alpha = 0f),
                uncheckedBoxColor = checkedColor.copy(alpha = 0f),
                disabledCheckedBoxColor = disabledColor,
                disabledUncheckedBoxColor = disabledColor.copy(alpha = 0f),
                disabledIndeterminateBoxColor = disabledIndeterminateColor,
                uncheckedBorderColor = uncheckedColor,
                disabledBorderColor = disabledColor,
                disabledIndeterminateBorderColor = disabledIndeterminateColor,
            )
        }
    }
}

우선 colors는 CheckboxColors가 들어가고 CheckboxColors는 interface이기 때문에 구현을 해야하는데 간단하게 이미 구현되어있는 구현체인 CheckboxDefaults를 통해 색의 변화를 주면서 어떻게 변화가 되는지 알아보자!

Checkbox(
    checked = true/false,
    onCheckedChange = {},
    enabled = true/false,
    colors = CheckboxDefaults.colors(
        checkedColor = Color.Blue,
        uncheckedColor = Color.Green,
        checkmarkColor = Color.Yellow,
        disabledColor = Color.Black,
        disabledIndeterminateColor = Color.Magenta // on,off 인지 상태값을 알 수 없을 때의 색
     )
)

겹치지 않게 다양한 색상을 넣어 확실하게 보이도록 했다.

위의 기본 코드에 checked와 enabled 값을 변경하면 다음와 같은 결과가 나온다.

checked enabled 결과물 사용된 색상
true true
checkedColor, checkmarkColor
true false
disabledColor, checkmarkColor
false true
uncheckedColor
false false
disabledColor

disabledIndeterminateColor도 예시를 보여주고 싶었는데 어떻게 구현할 수 있는지 모르겠어서 추가를 할 수 없었다.

나중에 찾으면 추가하겠다!

 

++ InteractionSource

component가 내보내는 이벤트에 해당하는 Interactions의 스트림을 나타낸다.
interactions는 누르거나 dragged 할 때 등 여러 상태에서 구성요소가 나타나는 방식을 변경할 수 있다.

클릭했을 때 효과 (ripple 등) 등을 컨트롤할 때 사용한다.

이 부분은 좀 더 공부하고 나중에 추가하도록 하겠다😂

우선 아래 링크들을 보고 참고해주면 좋겠다!

 

 

MutableInteractionSource  |  Android Developers

androidx.appsearch.builtintypes.properties

developer.android.com

 

 

Button Selector 구현 방법 # 버튼 눌렸을 때 Interaction Jetpack Compose

오늘은 Jetpack Compose에서 Button Selector를 구현하는 방법에 대해서 정리해 보도록 하겠습니다. 참고로 예전에 xml로 버튼 selector를 구현하는 방법은 아래 글에 정리되어 있습니다. >> Android 에서 Button

developer88.tistory.com