상세 컨텐츠

본문 제목

Android Compose ConstraintLayout

카테고리 없음

by 찐빵개발자 2023. 2. 15. 18:25

본문

https://developer.android.com/jetpack/compose/layouts/constraintlayout?hl=ko 

 

Compose의 ConstraintLayout  |  Jetpack Compose  |  Android Developers

Compose의 ConstraintLayout 컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요. ConstraintLayout은 화면에 다른 컴포저블을 기준으로 컴포저블을 배치할 수 있는 레이아웃

developer.android.com

 

 

Compose의 ConstraintLayout?

  • 화면에 다른 컴포저블을 기준으로 컴포저블을 배치할 수 있는 레이아웃
  • 더 복잡한 정렬 요구사항이 있는 더 큰 레이아웃을 구현할 때 유용

 

 

의존성 따로 추가해주어야 함

implementation "androidx.constraintlayout:constraintlayout-compose:1.0.1"

 

 

어떻게 쓸까? 

  •  createRefs() 또는 createRefFor()를 사용하여 ConstraintLayout에서 각 컴포저블의 참조만들기 
  • 제약 조건은 constrainAs() 수정자를 사용하여 제공
  • 제약 조건은 linkTo() 또는 다른 유용한 메서드를 사용하여 지정
  • parent ConstraintLayout 컴포저블 자체에 대한 제약 조건을 지정하는 데 사용할 수 있는 기존 참조

 

 

 

@Composable
fun ConstraintLayoutContent() {
    ConstraintLayout {
        // Create references for the composables to constrain
        val (button, text) = createRefs()

        Button(
            onClick = { /* Do something */ },
            // Assign reference "button" to the Button composable
            // and constrain it to the top of the ConstraintLayout
            modifier = Modifier.constrainAs(button) {
                top.linkTo(parent.top, margin = 16.dp)
            }
        ) {
            Text("Button")
        }

        // Assign reference "text" to the Text composable
        // and constrain it to the bottom of the Button composable
        Text("Text", Modifier.constrainAs(text) {
            top.linkTo(button.bottom, margin = 16.dp)
        })
    }
}

 

분리된 API (?)

  • 화면 구성 기반으로 제약 조건을 변경하거나 두 제약 조건 세트 사이에 애니메이션을 적용하는 경우 제약조건을 분리하면 좋다 -> 제약조건 변경할때 ConstraintSet을 전달하기만 하면 됨 
@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)
        }
    }
}

 

 

ConstraintLayout 개념

  • Guideline
    • 시각적 도우미
    • 특정 dp, percentage에 요소를 배치하는데에 유용 
    • 세로(start, end), 가로(top, bottom) 
 // Create guideline from the start of the parent at 10% the width of the Composable
val startGuideline = createGuidelineFromStart(0.1f)
// Create guideline from the end of the parent at 10% the width of the Composable
val endGuideline = createGuidelineFromEnd(0.1f)
//  Create guideline from 16 dp from the top of the parent
val topGuideline = createGuidelineFromTop(16.dp)
//  Create guideline from 16 dp from the bottom of the parent
val bottomGuideline = createGuidelineFromBottom(16.dp)
  • Barrier
    • 여러 컴포저블을 참조하여, 지정된 쪽에서 가장 극단적인 위젯을 기반으로 가상 가이드라인을 만듬
    • top, bottom, end, start 
val topBarrier = createTopBarrier(button, text)
  • Chain
    • 단일 축 (가로 or 세로) 에서 그룹과 같은 동작을 제공 
    • ChainStyle
      • Spread : 첫번째, 맨뒤 여유공간 포함하여 균등 분산
      • SpreadInside : 첫번째, 맨뒤 여유 공간 없이 균등 분산 
      • Packed : 모임 
val verticalChain = createVerticalChain(button, text, chainStyle = ChainStyle.Spread)
val horizontalChain = createHorizontalChain(button, text)