[Kotlin / Compose] ConstraintLayout

Subeen·2024년 4월 18일
0

Compose

목록 보기
7/20

ConstraintLayout

Jetpack Compose의 ConstraintLayout은 UI 요소들을 배치하는 데 사용되는 도구로 XML을 사용하는 대신에 코드로 UI를 작성할 수 있다. ConstraintLayout을 사용하여 UI 요소들의 위치, 크기, 간격을 선언적으로 정의할 수 있어 유연하고 반응형인 UI를 쉽게 만들 수 있다.

@Composable
fun ConstraintLayoutEx() {
	// ConstraintLayout을 생성하고 전체 공간을 채우는 Modifier를 적용한다.
    ConstraintLayout(modifier = Modifier.fillMaxSize()) {
    	// ConstraintLayout 내에 사용할 여러 개의 UI 요소에 대한 참조를 생성한다.
        val (redBox, magentaBox, greenBox, yellowBox) = createRefs()

		// 부모 ConstraintLayout의 바닥과 오른쪽 끝에 배치
        Box(
            modifier = Modifier
                .size(40.dp)
                .background(Color.Red)
                .constrainAs(redBox) {
                    bottom.linkTo(parent.bottom, margin = 8.dp)
                    end.linkTo(parent.end, margin = 4.dp)
                }
        )
        // 부모 ConstraintLayout의 양쪽 끝에 배치
        Box(
            modifier = Modifier
                .size(40.dp)
                .background(Color.Magenta)
                .constrainAs(magentaBox) {
                    start.linkTo(parent.start)
                    end.linkTo(parent.end)
                }
        )
        // 부모 ConstraintLayout의 가운데에 배치
        Box(
            modifier = Modifier
                .size(40.dp)
                .background(Color.Green)
                .constrainAs(greenBox) {
                    centerTo(parent)
                }
        )
        // magentaBox 오른쪽 아래에 배치
        Box(
            modifier = Modifier
                .size(40.dp)
                .background(Color.Yellow)
                .constrainAs(yellowBox) {
                    start.linkTo(magentaBox.end)
                    top.linkTo(magentaBox.bottom)
                }
        )

    }
}

createRefs()

createRefs()는 ConstraintLayout에서 사용되는 확장 함수로, 여러 개의 UI에 대한 참조를 생성하며 각 UI 요소에 대한 참조를 담은 Ref 객체를 반환한다.
이렇게 반환 된 Ref 객체들은 각각의 UI 요소에 대한 참조를 가지고 있으며, 이를 통해 해당 UI 요소들을 ConstraintLayout에서 내에서 배치할 때 사용할 수 있다.

constrainAs

constrainAs() 함수는 ConstraintLayout에서 사용되며, UI 요소를 부모 ConstraintLayout 내에서의 위치 및 크기를 지정하는 데 사용된다.

  • 이 함수는 UI 요소에 대한 제약 조건을 설정한다.
    • start, end, top, bottom을 사용하여 UI 요소를 부모의 특정 위치에 링크시킬 수 있다.
    • 다른 UI 요소의 start, end, top, bottom에 링크하여 UI 요소 간의 상대적인 위치를 정의할 수 있다.
    • UI 요소와 제약 조건 사이에 마진을 추가하여 간격을 조절할 수 있으며, 이는 UI 요소 간의 간격을 조절하거나 UI 요소와 부모 간의 여백을 추가하는 데 사용된다.

ConstraintSet를 사용하여 UI 구성

ConstraintLayout 내에서 각 UI 요소의 제약 조건을 별도로 정의하고, 그 제약 조건을 사용하여 UI를 배치하여 UI의 구조와 제약 조건을 분리하여 모듈화하고 재사용할 수 있으며 가독성이 향상 된다.

@Composable
fun ConstraintSetEx() {
	/*
    * ConstraintSet를 생성하고 각 UI 요소에 대한 제약 조건을 정의한다.
    * 각 UI 요소에 대해 createRefFor() 함수를 사용하여 참조를 생성하고.
    * constrain()를 사용하여 해당 UI 요소의 제약 조건을 설정한다. 
    */
   val constraintSet = ConstraintSet {
       val redBox = createRefFor("redBox")
       val magentaBox = createRefFor("magentaBox")
       val greenBox = createRefFor("greenBox")
       val yellowBox = createRefFor("yellowBox")

       constrain(redBox) {
           bottom.linkTo(parent.bottom, margin = 10.dp)
           end.linkTo(parent.end, margin = 30.dp)
       }

       constrain(magentaBox) {
           start.linkTo(parent.start, margin = 10.dp)
           end.linkTo(parent.end, margin = 30.dp)
       }

       constrain(greenBox) {
           centerTo(parent)
       }

       constrain(yellowBox) {
           start.linkTo(magentaBox.end)
           top.linkTo(magentaBox.bottom)
       }
   }

	/*
    * constraintSet 매개변수를 통해 UI 요소들의 위치를 설정하며,
    * 각 UI 요소는 layoutId를 사용하여 constraintSet에 지정한 참조와 연결된다.
    */
   ConstraintLayout(
       constraintSet = constraintSet,
       modifier = Modifier.fillMaxSize()) {
       Box(
           modifier = Modifier
               .size(40.dp)
               .background(Color.Red)
               .layoutId("redBox")
       )
       Box(
           modifier = Modifier
               .size(40.dp)
               .background(Color.Magenta)
               .layoutId("magentaBox")
       )
       Box(
           modifier = Modifier
               .size(40.dp)
               .background(Color.Green)
               .layoutId("greenBox")

       )
       Box(
           modifier = Modifier
               .size(40.dp)
               .background(Color.Yellow)
               .layoutId("yellowBox")

       )
   }
}

createRefFor()

createRefFor() 함수는 ConstraintSet 내에서 UI 요소에 대한 참조를 생성하는 데 사용된다.

val redBox = createRefFor("redBox")

redBox는 UI 요소에 대한 식별자이며, 이러한 식별자를 사용하여 constrain() 함수 등에서 해당 UI 요소에 대한 제약 조건을 설정할 수 있다.

constrain()

constrain() 함수는 ConstraintSet에서 UI 요소의 제약 조건을 설정하는 데 사용되며, UI 요소의 위치, 크기, 여백 등을 지정할 수 있다.

  • constrainAs()와 constrain()
    • 두 함수 모두 UI 요소의 제약 조건을 설정하는 데 사용된다.
    • constrain()는 주로 제약 조건 자체를 설정하는 데에 중점을 두고 있고, constrainAs()는 주로 UI 요소의 위치와 크기를 지정하는 데에 중점을 두고 있다.

chain

  • createVerticalChain
    • 여러 개의 UI 요소를 세로 방향으로 연결하여 체인을 형성한다.
    • 체인을 형성할 때, 각 요소들 간의 상대적인 위치 및 간격을 설정할 수 있다.
  • createHorizontalChain
    • 여러 개의 UI 요소를 가로 방향으로 연결하여 체인을 형성한다.
    • 각 요소들 간의 상대적인 위치 및 간격을 설정할 수 있다.
  • ChainStyle
    • ChainStyle.Packed : 각 요소들 사이의 간격이 최소화된다.
    • ChainStyle.Spread : 각 요소들 사이의 간격이 균등하게 분산된다.
    • ChainStyle.SpreadInsid : 각 요소들 사이의 간격이 균등하게 분산되지만, 체인의 첫 번째 요소와 체인의 시작 부분 사이, 그리고 마지막 요소와 체인의 끝 부분 사이에는 간격이 생길 수 있다.
@Composable
fun ConstraintLayoutEx() {
    ConstraintLayout(modifier = Modifier.fillMaxSize()) {
        val (redBox, magentaBox, greenBox, text) = createRefs()

        Box(
            modifier = Modifier
                .size(40.dp)
                .background(Color.Red)
                .constrainAs(redBox) {
                    top.linkTo(parent.top, margin = 18.dp)
                }
        )

        Box(
            modifier = Modifier
                .size(40.dp)
                .background(Color.Magenta)
                .constrainAs(magentaBox) {
                    top.linkTo(parent.top, margin = 32.dp)
                }
        )

        Box(
            modifier = Modifier
                .size(40.dp)
                .background(Color.Green)
                .constrainAs(greenBox) {
                    top.linkTo(parent.top, margin = 20.dp)
                }
        )

//        createVerticalChain(redBox, magentaBox, greenBox)
//        createHorizontalChain(redBox, magentaBox, greenBox)

//        createHorizontalChain(redBox, magentaBox, greenBox, chainStyle = ChainStyle.Packed)
//        createHorizontalChain(redBox, magentaBox, greenBox, chainStyle = ChainStyle.Spread)
        createHorizontalChain(redBox, magentaBox, greenBox, chainStyle = ChainStyle.SpreadInside)


//        val barrier = createTopBarrier(redBox, magentaBox, greenBox)
        val barrier = createBottomBarrier(redBox, magentaBox, greenBox)

        Text(
            text = "세 개의 박스 중 가장 아래에 배치되어 있는 박스 밑에 텍스트 출력",
            modifier = Modifier.constrainAs(text) {
                top.linkTo(barrier)
            }
        )
    }
}

createTopBarrier : 여러 UI 요소들의 상단 경계를 생성하며, 생성된 barrier는 이러한 요소들 중 가장 상단에 있는 요소의 상단 경계에 맞춰진다.
createBottomBarrier : 여러 UI 요소들의 하단 경계를 생성하며, 생성된 barrier는 이러한 요소들 중 가장 하단에 있는 요소의 하단 경계에 맞춰진다.

profile
개발 공부 기록 🌱

0개의 댓글