[Compose] Slot API와 잡동사니들

KSang·2024년 4월 16일
0

TIL

목록 보기
84/101

Slot API

Compose에서 화면을 구성할때 컴포저블을 후행 람다로 구현을 많이 한다고 한다.

컴포저블을 분리해서 관리하는데, 람다로 빼 놓으면 코드의 가독성이 더 좋아진다.

@Composable
fun CheckBoxWithSlot(
    checked: Boolean,
    setChecked: (Boolean) -> Unit,
    content: @Composable RowScope.() -> Unit //Align등을 설정하려면 스코프를 붙여줘야함, row,colunm,box 스콥 등
) {

    Row(
        modifier = Modifier.clickable { setChecked(checked.not()) },
        verticalAlignment = Alignment.CenterVertically
    ) {
        Checkbox(
            checked = checked,
            onCheckedChange = setChecked
        )
        content()
    }
}

간단한 체크 박스를 만들었다.

content를 맨 아래로 빼 줘서 후행 람다로 구현할 수 있게 만든다.

@Composable
fun ScaffoldEx() {
    val (checked, setChecked) = remember { mutableStateOf(false) }

    Scaffold(
        topBar = {
            TopAppBarEx(name = "Scaffold App")
        },
        floatingActionButton = {
            FloatingActionButton(
                onClick = { /**/ },
                modifier = Modifier.size(48.dp)
            ) {
                Icon(imageVector = Icons.Filled.AddCircle, contentDescription = "")
            }
        }
    ) { paddingValues ->
        Surface(
            modifier = Modifier
                .padding(paddingValues)
        ) {
            CheckBoxWithSlot(checked = checked, setChecked = setChecked) {
                Text(text = "체크 박스")
            }
        }
    }
}

여기서 CheckBoxWithSlot을 구현한 부분을 보면 람다로 컴포저블을 받아서 구현하는걸 볼 수 있다.

LazyColumn

리사이클러뷰 대신 컴포즈에서 쓰이는 lazyColumn을 다시 구현 해봤다.

이미지와 제목, 내용이 들어가 있는 card로 구성된 리스트를 만들 구현 해보자

@Composable
fun CatalogEx(itemList: List<ItemData>) {
    LazyColumn {
        items(itemList) { item ->
            Item(itemData = item)
        }
    }
}

LazyColumn 안에 items를 선언해 카드의 데이터들을 넣어준다.

그리고 각 카드의 아이템들의 Ui를 구현할 item컴포저블을 만들어준다.

@Composable
fun Item(itemData: ItemData){
    Card(
        elevation = CardDefaults.cardElevation(8.dp),
        modifier = Modifier.padding(16.dp)
    ) {
        ItemColumn(itemData)
    }
}

@Composable
fun ItemColumn(itemData: ItemData) {
    Column(
        modifier = Modifier.fillMaxWidth().padding(8.dp)
    ) {
        Image(
            painter = painterResource(id = itemData.imageId),
            contentDescription = itemData.title,
            modifier = Modifier.align(Alignment.CenterHorizontally)
        )
        Spacer(modifier = Modifier.size(8.dp))
        Text(
            text = itemData.title,
            style = MaterialTheme.typography.displaySmall
        )
        Spacer(modifier = Modifier.size(8.dp))
        Text(text = itemData.description)
    }
}

0개의 댓글