-
Android) Compose의 ConstraintLayoutAndroid 2022. 6. 1. 19:35
기존의 안드로이드에서 레이아웃의 중첩된 계층 구조의 성능을 개선하기 위해 ConstaintLayout을 사용했습니다.
Compose에서는 measure를 한 번만 하기 때문에 ConstraintLayout의 성능상 이점이 필요 없습니다.
다만, 개인적으로 뷰를 짜게 될 때 여전히 ConstraintLayout이 편하다는 생각이 들었습니다.
build.gradle
- 주의 사항으로 Compose의 버전과 Compose-ConstrainLayout의 버전이 다릅니다.
implementation "androidx.constraintlayout:constraintlayout-compose:1.0.0-beta02"
Compose-ConstrainLayout
- Compose-ConstratinLayout은 Kotlin DSL(Domain Specific Language)와 함께 작동합니다.
- ID를 생성하여 이를 참조하여 뷰의 배치를 구성할 수 있습니다.
- Modifier의 constraintAs()를 사용하여 생성한 ID를 Compose로 사용할 수 있습니다.
- ID를 하나를 생성하려면 createRef()로 생성합니다. 여러 ID를 생성하려면 createRefs()로 생성합니다.
- 기존의 ContsraintLayout의 app:layout_constraintTop_toTopOf 처럼 뷰들의 ID를 참조하여 연결하는 방식을 Compose-ConstraintLayout에서 linkTo를 통해 사용합니다.
@Composable fun ConstraintLayoutContent() { ConstraintLayout { // 참조할 ID 생성. val (button, text) = createRefs() Button( onClick = { /* Do something */ }, modifier = Modifier.constrainAs(button) { // linkTo를 통해 button의 top을 parent의 top에 오게한다. // parent의 top을 기준으로 16.dp 마진 top.linkTo(parent.top, margin = 16.dp) } ) { Text("Button") } Text("Text", Modifier.constrainAs(text) { // text의 top을 button의 bottom에 오게 한다. // button의 bottom을 기준으로 16.dp 마진 top.linkTo(button.bottom, margin = 16.dp) }) } }
- Text를 중앙에 배치하려면, centerHorizontallyTo를 사용합니다.
- 다만, Text를 centerHorizontallyTo를 parent로 줬는데, Button 기준으로 중앙에 배치된 것처럼 보입니다.
- 이는 자식 Composables를 표현할 수 있는 최소한의 크기만을 사용하기 때문입니다.
- 전체 화면으로 확장해서 사용하려면 Modifier의 fillMaxSize, size 등을 사용하면 됩니다.
@Composable fun ConstraintLayoutContent() { ConstraintLayout { ... Text("Text", Modifier.constrainAs(text) { top.linkTo(button.bottom, margin = 16.dp) centerHorizontallyTo(parent) }) } }
분리된 API
- 화면 구성에 따라 다르게 ConstraintLayout을 구성할 때 이를 분리시켜 사용할 수 있습니다.
- ConstraintSet을 ConstraintLayout 생성 시 파라미터로 전달합니다.
- ConstraintLayout에서는 ConstraintSet에서 정의해놓은 구성에서 ID만 입력해 사용할 수 있습니다.
@Composable fun DecoupledConstraintLayout() { BoxWithConstraints { val constraints = if (minWidth < 600.dp) { decoupledConstraints(margin = 16.dp) // Portrait constraints } else { decoupledConstraints(margin = 32.dp) // Landscape constraints } ConstraintLayout(constraints) { Button( onClick = { /* Do something */ }, modifier = Modifier.layoutId("button") ) { Text("Button") } Text("Text", Modifier.layoutId("text")) } } } private fun decoupledConstraints(margin: Dp): ConstraintSet { return ConstraintSet { val button = createRefFor("button") val text = createRefFor("text") constrain(button) { top.linkTo(parent.top, margin = margin) } constrain(text) { top.linkTo(button.bottom, margin) } } }
반응형'Android' 카테고리의 다른 글
핵심만 골라 배우는 젯팩 컴포즈 Study 1주차 (0) 2023.01.25 Android) Kotlin Coroutines 1.6에서 도입된 테스트 API 사용해보기 (1) 2022.08.21 Android) 안드로이드 12 Splash Screen 대응하기 (2) 2022.03.09 Android) BroadcastReciever와 LiveData로 실시간 네트워크 연결 감지하기 (0) 2022.01.17 Android) Jetpack Compose에서 Paging 라이브러리 사용해보기 (0) 2021.12.04