Android/Jetpack Compose

[Jetpack Compose] Slot API

chattymin 2023. 7. 7. 01:03
728x90
반응형

Slot API

이름을 보면 알 수 있는 것 처럼 뭔갈 넣을 수 있도록 만드는 것이다. 즉 재사용성이 좋도록 함수를 설계하는 것이다.

말만 들어서는 기존의 재사용성 높은 함수와 다를바가 없어 보일 것이다. 자세하게 정리하며 설명 들어가보자.

 

 

목적

일단 이걸 왜 써야할까? 앞서 말했던것 처럼 재사용성이다. 극한의 재사용성이 목표다. 하나의 큰 틀을 만들고, 그 틀을 세부적으로 활용하며 사용하기 위해서 Slot API를 사용한다. 아래 사용법을 보면서 공부해보자.

 

 

사용법

기존의 코드를 먼저 보자.

@Composable
fun ButtonFun(){
    var count = remember {
        mutableStateOf(0)
    }

    Row(
        verticalAlignment = Alignment.CenterVertically
    ) {
        Button(onClick = { count.value++ }) {
            Text(text = count.value.toString())
        }
        Text(text = "Click!")
    }
}

클릭할때마다 글자가 바뀌는 버튼을 만들면 대략 위와 같은 느낌이 가장 먼저 생각날거다. 

 

여기서 count를 외부에서 받아와서 적용하는 방법을 쓴다면, 한층 재사용성이 높아진다.

@Composable
fun ButtonFun(
    count: MutableState<Int>
){
    Row(
        verticalAlignment = Alignment.CenterVertically
    ) {
        Button(onClick = { count.value++ }) {
            Text(text = count.value.toString())
        }
        Text(text = "Click!")
    }
}

count는 외부에서 선언하고, 함수 내부에서 사용할 수 있다. 즉, 함수와 count 변수와의 의존성을 없애는 것이다.

 

여기서 count가 클릭되었을때 실행되는 함수 또한 외부에서 받아올 수 있다.

@Composable
fun ButtonFun(
    count: Int,
    onClick: () -> Unit
){
    Row(
        verticalAlignment = Alignment.CenterVertically
    ) {
        Button(onClick = { onClick() }) {
            Text(text = count.toString())
        }
        Text(text = "Click!")
    }
}

외부에 존재하는 count를 가져오고, 그 값을 변경시키는 코드(버튼이 클릭되었을때 사용되는 코드)를 외부에서 가져와서 함수와의 의존성 또한 없앨 수 있다. 이때 count가 Mutable값이 단순 Int로 변화하는 이유는 무엇일까? 정답은 의존성의 변화이다. onClick함수가 외부에서 선언되기 때문에 count의 값 또한 외부에서 변화를 줘야 한다. 

 

여기서 내부에 존재하는 Text또한 외부에서 가져올 수 있다. 

@Composable
fun ButtonFun(
    count: Int,
    onClick: () -> Unit,
    content: @Composable () -> Unit
){
    Row(
        verticalAlignment = Alignment.CenterVertically
    ) {
        Button(onClick = { onClick() }) {
            Text(text = count.toString())
        }
        content()
    }
}

content: @Composable () -> Unit 이게 핵심이다.

외부에서 Composable 함수를 가져와서 내부에 사용할 수 있다. 겉으로 보기엔 Text를 내부에 적는것과 다를게 없어 보인다. 하지만, 결정적인 차이점이 존재한다. 바로 재사용성이다.

 

이게 뭔소린가 싶을 수도있다. 매개변수로 Text를 받으면 재사용성이 좋지 않나?? 싶을 수 있다.

매개변수가 Text라면 Text만 받을 수 있지만, Composable로 한다면 Text뿐만 아니라 Button, Image 등 다양한 Composabel 함수들을 매개변수로 사용할 수 있다.

 

여기서 한단계 더 발전시켜보자.

@Composable
fun ButtonFun(
    count: Int,
    onClick: () -> Unit,
    content: @Composable RowScope.() -> Unit
){
    Row(
        verticalAlignment = Alignment.CenterVertically
    ) {
        Button(onClick = { onClick() }) {
            Text(text = count.toString())
        }
        content()
    }
}

RowScope라는걸 추가해줬다. 왜일까?

내부에 Row가 존재하고있다. 그리고, content가 Row내부에 사용되고 있기 때문에 RowScope가 적용될 수 있도록 사용해준 것이다.

 

 

 

결론

꽤나 유용하다. 버튼들을 만들때도 사용할 수 있을것 같다. 이것 외에도 같은 틀을 가진 함수를 여러개 만들어야 할때 주로 사용할 수 있을 것 같다.

728x90
반응형