Android Jetpack Compose UI/Compose Layout

[Compose Layout] 4. Compose Box 사용법 정리

반응형

Box Layout이란?

Box Layout은 여러 위젯를 겹쳐서 놓을 수 있는 레이아웃이다.  Box 내부의 Child Compose들은 Modifier.align에 자신의 위치를 지정함으로써 Box 내부의 어떤 공간에 보여질지를 결정할 수 있다. 두개의 위젯을 같은 위치로 설정하면 위젯 위에 다른 위젯 겹쳐 지는 것 또한 가능하다.

 

Box Layout은 기존 Frame Layout과 동작이 동일한데, 화면 오른쪽 아래 버튼을 만들거나 할 때 유용하다.

 

예를 들어 아래 코드와 같이 Box 내부에 다음과 같이 align이 없는 상태로 Text를 쓰게되면

@Preview(showBackground = true, widthDp = 120, heightDp = 200)
@Composable
fun KotlinWorldBox1() {
    Box {
        Text(text = "Kotlin")
        Text(text = "World")
        Text(text = "Blog")
    }
}

아래 그림1과 같이 텍스트가 겹쳐서 나오게 된다.

그림1. align이 없는 경우

 

이 텍스트를 순서대로 왼쪽 위, 중앙, 오른쪽 아래에 배치시키기 위해서는 다음과 같이 옵션을 주면 된다.

@Preview(showBackground = true, widthDp = 120, heightDp = 200)
@Composable
fun KotlinWorldBox() {
    Box {
        Text(modifier = Modifier.align(Alignment.TopStart), text = "Kotlin")
        Text(modifier = Modifier.align(Alignment.Center), text = "World")
        Text(modifier = Modifier.align(Alignment.BottomEnd), text = "Blog")
    }
}

그림2. align을 준 Text Widget

Box  내부 살펴보기

Box는 modifier, contentAlignment, propateMinConstraints, content 네가지 변수를 받는다. 

@Composable
inline fun Box(
    modifier: Modifier = Modifier,
    contentAlignment: Alignment = Alignment.TopStart,
    propagateMinConstraints: Boolean = false,
    content: @Composable BoxScope.() -> Unit
)
  • modifier(수정자) : 박스의 크기, 클릭 이벤트 등을 정의 가능
  • contentAlignment : 자식의 기본 정렬 방식을 결정
  • propagateMinConstraints : 최소 제약 조건을 전파시키는지 여부
  • content : Box 레이아웃에 들어갈 레이아웃과 위젯이 람다식으로 들어가는 부분

 

modifier은 다른 레이아웃, 위젯들과 모두 공통으로 쓰이므로 이 글에서는 다루지 않는다. 나머지 또한 중요하지 않으므로, 그려지는 관점에서 중요한 contentAlignment와 contentAlignment만 보도록 하자.

 

ContentAlignment

contentAligment는 Box 내부의 자식 위젯들의 기본 위치를 지정하는 값이다. 이 값이 지정되면  BoxScope에 있는 자식들의 기본 align이 이 값으로 지정된다. 

 

예를 들어 아래와 같이 ContentAlignment를 지정할 경우 BoxScope 내부의 세개의 Text는 align이 BottomEnd(오른쪽 아래)로 지정된다.

@Preview(showBackground = true, widthDp = 120, heightDp = 200)
@Composable
fun KotlinWorldBox1() {
    Box(contentAlignment = Alignment.BottomEnd) {
        Text(text = "Kotlin")
        Text(text = "World")
        Text(text = "Blog")
    }
}

그림3. contentAlignment 지정

하지만, 이 값은 내부의 자식 위젯들의 Modifier에 align이 적용된 경우에는 동작하지 않는다. 예를 들어 아래와 같은 코드를 수행할 경우

 자식들이 이미 자체 align을 가지고 있기 때문에 Box의 alignment가 전파되지 않는다.

@Preview(showBackground = true, widthDp = 120, heightDp = 200)
@Composable
fun KotlinWorldBox() {
    Box(contentAlignment = Alignment.BottomEnd) {
        Text(modifier = Modifier.align(Alignment.TopStart), text = "Kotlin")
        Text(modifier = Modifier.align(Alignment.Center), text = "World")
        Text(modifier = Modifier.align(Alignment.BottomEnd), text = "Blog")
    }
}

그림4. 자식의 alignment가 지정되는 경우

propagateMinConstraints

Box에서 이 값은 지정하지 않을 경우 false로 되어 있다. 만약 이 값이 false로 되어 있으면 Box의 MinConstraint가 적용되지 않은 상태로 Child Widget들이 measure된다. 하지만 이 값이 true가 된다면 Box의 MinContraint가 적용된 상태로 Child들이 measure된다.

즉, 이 값이 true면 Box의 min size constraint 가  child에도 적용이 되게 된다. 

반응형

 

이 글의 저작권은 Dev World 에 있습니다. 글, 이미지 무단 재배포 및 변경을 금지합니다.