#Material3 Checkbox 공식 문서
=>https://m3.material.io/components/checkbox/guidelines
-여러 관련 옵션을 목록에서 선택하고자 할 때는 스위치 대신에 체크박스를 사용해야 한다. 이는 유사한 항목을 시각적으로 효과적이게 그룹화하고 스위치 보다 공간을 덜 차지하기 때문이다.
-구글에서는 체크박스를 사용 할때 텍스트 라벨과 함께 사용하여 선택 옵션을 명확하게 사용자에게 전달하도록 권장하고 있다.
-체크박스는 사용자에게 하나 또는 그 이상의 옵션을 리스트에서 선택 할 수 있게 해준다. 부모 체크박스를 사용해서 자식 체크박스들을 전체 체크 또는 전체 체크 해제 할 수 있게 해준다. 즉, 부모 체크박스의 체크여부를 모든 자식 체크박스들이 받아들여야 한다. 즉, 체크박스들은 다른 체크박스들과 부모-자식 관계를 맺을 수 있다는 의미이다.
-위에 대한 내용을 구글에서는 이렇게 사진으로 표현해주고 있다.
-체크박스 이외에 선택을 가능하게 해주는 UI는 radio buttons , switches가 있다 이 세가지의 공통점은 사용자에게 선택기능을 줄 수 있다는 것이다. 하지만 각기 다른 경우에 상황에 알맞게 사용해야 한다. [1.체크박스는 관련있는 선택지들의 리스트 내부에서 선택지들을 선택하도록 유도하고자 할 때] , [2.라디오버튼은 관련있는 선택지들의 리스트 내부에서 선택지를 단 하나만 선택하도록 유도하고자 할 때] , [3.스위치는 목록에서 설정과 같은 독립형 옵션 또는 더 자세한 옵션을 선택하도록 유도하고자 할 때] 이렇게 3가지의 경우에 사용한다.
-체크박스의 구성요소를 담을 데이터 클래스 선언 : 이 데이터 클래스의 객체를 체크 박스 한개라고 생각하면 된다.
data class CheckInfo(
val isChecked: Boolean,
val text: String
)
@Composable
fun Checkboxes() {
val checkboxes = remember {
mutableStateListOf(
CheckInfo(
isChecked = false,
text = "1"
),
CheckInfo(
isChecked = false,
text = "2"
),
CheckInfo(
isChecked = false,
text = "3"
),
)
}
var allState by remember {
mutableStateOf(ToggleableState.Indeterminate)
}
val toggleTriState = {
allState = when (allState) {
ToggleableState.Indeterminate -> ToggleableState.On
ToggleableState.On -> ToggleableState.Off
else -> ToggleableState.On
}
checkboxes.indices.forEach { index ->
> .copy()를 사용해서 기존의 checkbox의 isChecked 값만 변경된 새로운 객체를 반환한다.
checkboxes[index] = checkboxes[index].copy(
isChecked = allState == ToggleableState.On
)
}
}
Row(
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier
.clickable {
toggleTriState()
}
.padding(end = 16.dp)
) {
TriStateCheckbox(
state = allState,
onClick = toggleTriState
)
Text("전체 클릭")
}
checkboxes.forEachIndexed { index, info ->
Row(
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier
.padding(start = 32.dp)
.clickable {
checkboxes[index] = info.copy(
isChecked = !info.isChecked
)
}
.padding(end = 16.dp)
) {
Checkbox(
checked = info.isChecked,
onCheckedChange = { isChecked ->
checkboxes[index] = info.copy(
isChecked = isChecked
)
})
Text(text = info.text)
}
}
}
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
VelogSelectionUiComponentTheme {
Column(
modifier = Modifier
.fillMaxSize()
.padding()
) {
Checkboxes()
}
}
}
}
}
data class CheckInfo(
val isChecked: Boolean,
val text: String
)
@Composable
fun Checkboxes() {
val checkboxes = remember {
mutableStateListOf(
CheckInfo(
isChecked = false,
text = "1"
),
CheckInfo(
isChecked = false,
text = "2"
),
CheckInfo(
isChecked = false,
text = "3"
),
)
}
var allState by remember {
mutableStateOf(ToggleableState.Indeterminate)
}
val toggleTriState = {
allState = when (allState) {
ToggleableState.Indeterminate -> ToggleableState.On
ToggleableState.On -> ToggleableState.Off
else -> ToggleableState.On
}
checkboxes.indices.forEach { index ->
checkboxes[index] = checkboxes[index].copy(
isChecked = allState == ToggleableState.On
)
}
}
Row(
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier
.clickable {
toggleTriState()
}
.padding(end = 16.dp)
) {
TriStateCheckbox(
state = allState,
onClick = toggleTriState
)
Text("전체 클릭")
}
checkboxes.forEachIndexed { index, info ->
Row(
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier
.padding(start = 32.dp)
.clickable {
checkboxes[index] = info.copy(
isChecked = !info.isChecked
)
}
.padding(end = 16.dp)
) {
Checkbox(
checked = info.isChecked,
onCheckedChange = { isChecked ->
checkboxes[index] = info.copy(
isChecked = isChecked
)
})
Text(text = info.text)
}
}
}
-