Slot API

박채빈·2024년 1월 24일
0

AndroidStudy

목록 보기
5/19
post-thumbnail

Slot API

  • 어떤 Composable 함수가 다른 Composable 함수가 Component를 포함할 수 있는 것
  • Colum, Row, TopAppBar 등

Default

@Composable
fun SlotEx() {
  val (checked1, setChecked1) = remember { mutableStateOf(false) }
  val (checked2, setChecked2) = remember { mutableStateOf(false) }

  Column {
    Row(
      verticalAlignment = Alignment.CenterVertically
    ) {
      Checkbox(checked = checked1, onCheckedChange = setChecked1)
      Text(text = "Text1", modifier = Modifier.clickable { setChecked1(!checked1) })
    }

    Row(
      verticalAlignment = Alignment.CenterVertically
    ) {
      Checkbox(checked = checked2, onCheckedChange = setChecked2)
      Text(text = "Text2", modifier = Modifier.clickable { setChecked2(!checked2) })
    }
  }
}

Composable 함수로 분해

@Composable
fun CheckBoxWithText(checked: MutableState<Boolean>, text: String) {
  Row(
    verticalAlignment = Alignment.CenterVertically
  ) {
    Checkbox(checked = checked.value, onCheckedChange = { checked.value = it })
    Text(text = text, modifier = Modifier.clickable { checked.value = !checked.value })
  }
}

@Composable
fun SlotEx() {
  val checked1 = remember { mutableStateOf(false) }
  val checked2 = remember { mutableStateOf(false) }

  Column {
    CheckBoxWithText(checked = checked1, "Text1")
    CheckBoxWithText(checked = checked2, "Text2")
  }
}

@Composable () -> Unit 타입으로 content를 받아오기

@Composable
fun CheckBoxWithSlot(
  checked: MutableState<Boolean>,
  content: @Composable () -> Unit
) {
  Row(
    verticalAlignment = Alignment.CenterVertically,
    modifier = Modifier.clickable { checked.value = !checked.value }
  ) {
    Checkbox(checked = checked.value, onCheckedChange = { checked.value = it })
    content()
  }
}

@Composable
fun SlotEx() {
  val checked1 = remember { mutableStateOf(false) }
  val checked2 = remember { mutableStateOf(false) }

  Column {
    CheckBoxWithSlot(checked = checked1) { Text(text = "Text1") }
    CheckBoxWithSlot(checked = checked2) { Text(text = "Text2") }
  }
}

Text를 만드는 책임을 옮김
Row에도 clickable이 있고 Checkbox에도 onCheckecChange가 있어야 함.

content 타입을 @Composable RowScope.() -> Unit 으로 변경

@Composable
fun CheckBoxWithSlot(
  checked: MutableState<Boolean>,
  content: @Composable RowScope.() -> Unit
) {
  Row(
    verticalAlignment = Alignment.CenterVertically,
    modifier = Modifier.clickable { checked.value = !checked.value }
  ) {
    Checkbox(checked = checked.value, onCheckedChange = { checked.value = it })
    content()
  }
}

@Composable
fun SlotEx() {
  val checked1 = remember { mutableStateOf(false) }
  val checked2 = remember { mutableStateOf(false) }

  Column {
    CheckBoxWithSlot(checked = checked1) { 
      Text(text = "Text1", modifier = Modifier.align(Alignment.CenterVertically)) 
    }
    CheckBoxWithSlot(checked = checked2) { 
      Text(text = "Text2") 
    }
  }
}

사용하는 쪽에서도 해당 Scope의 이점을 가져갈 수 있음
Column scope 쓰고 싶으면 @Composable ColumnScope.() -> Unit으로 바꾸고 내부에서도 Column으로 쓰면 됨

상태를 바꾸는 람다를 @Composable의 인자로 빼기

@Composable
fun CheckBoxWithSlot(
  checked: Boolean,
  onCheckedChanged: () -> Unit,
  content: @Composable RowScope.() -> Unit
) {
  Row(
    verticalAlignment = Alignment.CenterVertically,
    modifier = Modifier.clickable { onCheckedChanged() }
  ) {
    Checkbox(checked = checked, onCheckedChange = { onCheckedChanged() })
    content()
  }
}

@Composable
fun SlotEx() {
  var checked1 by remember { mutableStateOf(false) }
  var checked2 by remember { mutableStateOf(false) }

  Column {
    CheckBoxWithSlot(
      checked = checked1,
      onCheckedChanged = { checked1 = !checked1 }
    ) {
      Text(text = "Text1", modifier = Modifier.align(Alignment.CenterVertically))
    }
    CheckBoxWithSlot(
      checked = checked2,
      onCheckedChanged = { checked2 = !checked2 }
    )
    {
      Text(text = "Text2")
    }
  }
}
profile
안드로이드 개발자

0개의 댓글