Column: Compose에서 수직 배치 및 컨테이너 구성

저자: IT Sectr 게시일: 2026-06-28 읽는 시간: 8 분

Column은 Jetpack Compose의 내장 Composable 컴포넌트로, compose.foundation.layout 패키지에 포함되어 있으며 자식 요소를 수직으로, 하나씩 아래로 배치합니다. Column은 기존 View 시스템의 수직 방향 LinearLayout과 동등하지만, 선언적 설명을 사용하고 상태 변화에 자동으로 반응합니다. Google Android Developers, 2026에 따르면 Column은 Row 및 Box와 함께 세 가지 기본 컨테이너 중 하나입니다.

주요 포인트

  • Column은 Arrangement 및 Alignment 설정으로 요소를 수직으로 배치합니다
  • Arrangement는 요소 간 수직 공간 분배를 정의합니다
  • Alignment는 Column 내 각 요소의 수평 정렬을 설정합니다
  • Weight는 빈 공간을 요소 간에 비례하여 분배합니다
  • IntrinsicSize를 사용하면 Column이 자식의 최소/최대 너비에 맞게 크기를 조정할 수 있습니다

Jetpack Compose에서 Column이란

Column은 선택적 매개변수(modifier, verticalArrangement, horizontalAlignment, content)를 받는 Composable 함수이며, content는 ColumnScope를 가진 람다입니다. Column 내에서 자식 Composable 함수는 선언 순서대로 위에서 아래로 배치됩니다. Column의 높이는 자식 높이의 합에 Arrangement로 지정된 공간을 더한 값입니다. 너비는 Alignment를 고려한 최대 자식 너비입니다.

Column은 보이지 않는 컨테이너입니다. 기본적으로 배경이나 테두리가 없습니다. 배경이 필요하면 Column 자체에 Modifier.background()를 추가하세요. LazyColumn과 달리 Column은 모든 자식 요소를 동시에 렌더링하며 가상화를 지원하지 않습니다. 즉, Column은 소규모 데이터 세트(최대 10-15개 요소)에만 적합합니다. 긴 목록에는 LazyColumn을 사용하세요.

ColumnScope는 Column의 content 람다를 위한 리시버입니다. Column 내에서만 작동하는 추가 Modifier(weight(), align(), alignByBaseline())를 제공합니다. 이러한 Modifier는 수직 레이아웃 특성에 의존하므로 Column 외부에서는 의미가 없습니다. 예를 들어, Modifier.align(Alignment.CenterHorizontally)는 자식 요소를 Column의 중앙에 수평으로 정렬합니다.

Column 매개변수: Arrangement, Alignment, Modifier

VerticalArrangement는 요소 간 수직 공간 분배 방식을 결정합니다. 사용 가능한 값: Arrangement.Top(기본값), Bottom, Center, SpaceBetween, SpaceEvenly, SpaceAround. Column의 높이가 요소 높이의 합보다 크면 Arrangement가 빈 공간을 분배합니다. 요소가 전체 높이를 차지하면 Arrangement는 효과가 없습니다.

HorizontalAlignment는 각 자식 요소의 수평 정렬을 설정합니다. Alignment.Start(LTR 기본값), CenterHorizontally, End. Alignment는 각 요소에 독립적으로 작용합니다. 한 요소가 좁고 다른 요소가 넓으면 첫 번째 요소는 정렬되지만 두 번째 요소는 Column 경계를 벗어날 수 있습니다. Alignment는 Column이 고정 너비 또는 fillMaxWidth를 가질 때만 작동합니다.

Column용 Modifier: Column은 컨테이너 자체에 적용되는 Modifier를 받습니다. Modifier.fillMaxWidth(), fillMaxHeight(), size(), padding() — 모든 표준 Modifier가 작동합니다. 특별 참고: Modifier.height(IntrinsicSize.Min)는 Intrinsic 측정을 사용하여 자식 요소를 기반으로 최소 높이를 계산하도록 Column을 강제합니다.

kotlin
@Composable
fun ColumnArrangementDemo() {
    Column(
        modifier = Modifier.fillMaxSize().background(Color(0xFFF5F5F5)),
        verticalArrangement = Arrangement.SpaceEvenly,
        horizontalAlignment = Alignment.CenterHorizontally
    ) {
        Text("위", modifier = Modifier.background(Color.Cyan))
        Text("중간", modifier = Modifier.background(Color.Magenta))
        Text("아래", modifier = Modifier.background(Color.Yellow))
    }
}

    // IntrinsicSize: Column이 콘텐츠에 맞게 높이 조정
@Composable
fun IntrinsicColumn() {
    Column(
        modifier = Modifier
            .height(IntrinsicSize.Min)
            .width(200.dp)
    ) {
        Text("짧은 텍스트")
        Text("열 내에서 줄바꿈되는 매우 긴 텍스트")
    }
}
Arrangement동작
Arrangement.Top요소가 위쪽에 붙고, 빈 공간은 아래쪽
Arrangement.Center요소가 중앙에, 공간은 위아래 균등 분배
Arrangement.SpaceBetween첫 번째 요소 위, 마지막 요소 아래, 나머지 균등
Arrangement.SpaceEvenly모든 요소와 가장자리 사이가 동일한 간격
Arrangement.SpaceAround요소 간 동일 간격, 가장자리는 절반 간격

Column weight: 요소 간 공간 분배

Modifier.weight()는 ColumnScope Modifier로, Column 요소 간의 빈 수직 공간을 지정된 가중치에 비례하여 분배합니다. Column이 400dp 높이를 차지하고 자식 요소 합계가 100dp인 경우 나머지 300dp는 weight 요소 간에 분할됩니다. weight(2f) 요소는 weight(1f) 요소보다 두 배의 공간을 얻습니다.

fill — weight의 두 번째 매개변수: weight(weight: Float, fill: Boolean = true). fill = true(기본값)인 경우 요소는 사용 가능한 전체 높이로 늘어납니다. fill = false인 경우 요소는 자체 고유 높이만 차지하고 나머지 공간은 비어 있습니다. 이는 요소가 한쪽에 붙어 있어야 하지만 weight가 빈 공간 분배 비율만 정의하는 경우에 유용합니다.

Weight 제한사항: weight는 고정 높이 또는 fillMaxHeight()가 있는 Column에서만 작동합니다. Column의 높이가 자식 요소(wrap content)에 의해 결정되면 가중치는 의미가 없습니다 — 분배할 빈 공간이 없기 때문입니다. 또한 동일한 요소에서 weight를 Modifier.height()와 결합할 수 없습니다 — 충돌이 발생하고 weight가 무시됩니다.

kotlin
@Composable
fun WeightedColumn() {
    Column(
        modifier = Modifier.fillMaxHeight().width(300.dp)
    ) {
        // 높이의 1/6 차지(weight 1, 합계 1+2+3=6)
        Box(
            modifier = Modifier
                .weight(1f)
                .fillMaxWidth()
                .background(Color.Red)
        )
        // 높이의 2/6 차지
        Box(
            modifier = Modifier
                .weight(2f)
                .fillMaxWidth()
                .background(Color.Green)
        )
        // 높이의 3/6 차지
        Box(
            modifier = Modifier
                .weight(3f)
                .fillMaxWidth()
                .background(Color.Blue)
        )
    }
}

Column vs LazyColumn: 각각 사용해야 할 때

Column은 모든 자식 요소를 즉시 렌더링합니다. 10-15개 이상의 요소가 있으면 Column은 컴포지션 및 측정에 상당한 부하를 만듭니다. 반면 LazyColumn은 보이는 요소만 렌더링하고 보이지 않는 요소를 재사용합니다. 긴 목록, 수천 개 요소의 목록, 무한 목록 또는 채팅에는 LazyColumn이 필수입니다.

Column이 더 나은 경우: 양식 화면(3-10개 필드), 프로필 카드, 아이콘이 있는 수직 열, 메뉴. Column은 IntrinsicSize도 지원하여 적응형 높이에 유용합니다. 또한 Column은 디버깅이 더 쉽습니다 — 가상화가 없어 모든 요소가 Layout Inspector에 표시됩니다. 정적 UI의 경우 Column이 올바른 선택입니다.

LazyColumn 제공: 아이템 캐싱, 키 기반 식별, 추가/제거 애니메이션(animateItemPlacement), 고정 헤더(sticky headers). 목록에 다른 유형의 요소(다른 viewType)가 포함된 경우 items에서 sealed class와 함께 LazyColumn을 사용하세요. Column은 고정 헤더를 지원하지 않습니다(스크롤 가능한 Column을 통해 에뮬레이션 필요). 또한 LazyColumn은 GridCells 사용 시 LazyVerticalGrid를 지원합니다.

기준ColumnLazyColumn
요소 수최대 10-15모든 수
성능항상 모두 렌더링보이는 것만 + 버퍼
스크롤Modifier.verticalScroll 통해내장
IntrinsicSize지원미지원
고정 헤더없음(에뮬레이션)있음(stickyHeader)
요소 애니메이션내장 없음animateItemPlacement

Column 사용 실용 예제

사용자 프로필 화면을 살펴보겠습니다. 여기서 Column은 아바타, 이름, 자기소개 및 작업 버튼의 주요 컨테이너로 사용됩니다. IntrinsicSize.Min을 사용한 Column은 콘텐츠에 맞게 조정되며, weight는 섹션 간 공간 분배에 사용됩니다.

kotlin
@Composable
fun UserProfileCard(name: String, bio: String) {
    Card(
        modifier = Modifier.fillMaxWidth().padding(16.dp),
        elevation = CardDefaults.cardElevation(defaultElevation = 4.dp)
    ) {
        Column(
            modifier = Modifier.fillMaxWidth().padding(16.dp),
            horizontalAlignment = Alignment.CenterHorizontally,
            verticalArrangement = Arrangement.spacedBy(8.dp)
        ) {
            // 아바타
            Icon(
                imageVector = Icons.Default.AccountCircle,
                contentDescription = "Avatar",
                modifier = Modifier.size(64.dp)
            )
            // 이름
            Text(name, style = MaterialTheme.typography.headlineSmall)
            // 자기소개
            Text(bio, style = MaterialTheme.typography.bodyMedium,
                modifier = Modifier.padding(top = 4.dp))
            // 작업 버튼
            Row(
                horizontalArrangement = Arrangement.spacedBy(12.dp),
                modifier = Modifier.padding(top = 12.dp)
            ) {
                Button(onClick = { }) { Text("메시지") }
                OutlinedButton(onClick = { }) { Text("팔로우") }
            }
        }
    }
}

예제에서 Column은 요소 간 균일한 간격을 위해 Arrangement.spacedBy(8.dp)를 사용합니다. horizontalAlignment = CenterHorizontally는 아바타, 이름, 자기소개를 중앙에 정렬합니다. Column 내부의 Row는 한 줄의 버튼을 위한 중첩 컨테이너입니다. Column(수직 배치)과 Row(수평 배치)의 조합은 Compose에서 UI 구축의 일반적인 패턴입니다.

자주 묻는 질문

성능 측면에서 Column과 LazyColumn의 차이점은 무엇인가요?

Column은 모든 자식 요소를 한 번에 렌더링하므로 100개 이상의 요소에서 FPS가 떨어집니다. LazyColumn은 보이는 요소와 버퍼(보통 3-5개 화면)만 렌더링합니다. 3-10개 요소의 정적 화면에서는 가상화 오버헤드가 없으므로 Column이 더 빠릅니다.

Column을 스크롤 가능하게 하려면 어떻게 하나요?

Column에 Modifier.verticalScroll(rememberScrollState())를 추가하세요. Column이 스크롤 가능해지지만 가상화는 제공되지 않습니다 — 모든 요소가 여전히 한 번에 렌더링됩니다. 긴 스크롤 가능 목록에는 LazyColumn을 사용하세요.

Row 안에 Column, Column 안에 Row를 중첩할 수 있나요?

네, Row/Column의 중첩은 일반적인 방법입니다. 두 컨테이너를 결합하여 복잡한 그리드를 구축할 수 있습니다. 그러나 불필요한 깊은 중첩(4+ 레벨)은 피하세요 — LayoutNode 측정 횟수가 증가하고 컴포지션이 느려집니다.

Column에서 모든 요소의 너비를 동일하게 하려면 어떻게 하나요?

각 자식 요소에 Modifier.fillMaxWidth()를 사용하세요. Column이 Modifier.fillMaxWidth()를 가진 경우 fillMaxWidth()를 가진 모든 자식이 전체 너비로 늘어납니다. 대안: Column이 고정 컨테이너 내에 있는 경우 ColumnScope에서 Modifier.weight(1f)를 사용하세요.

Column에서 spacedBy는 어떻게 작동하나요?

Arrangement.spacedBy(space)는 인접한 두 요소 사이에 고정 간격을 추가합니다. SpaceBetween/SpaceAround와 달리 spacedBy는 요소를 늘리지 않습니다 — 간격은 고정이며 나머지 공간은 Column 끝에 남습니다. spacedBy는 첫 번째 요소 앞이나 마지막 요소 뒤에 간격을 추가하지 않습니다.

요약

  • Column — 요소를 위에서 아래로 배치하는 Compose의 기본 수직 컨테이너
  • Arrangement가 공간 분배 제어(Top, Center, SpaceBetween, spacedBy)
  • Alignment가 각 자식 요소의 수평 정렬 설정
  • Weight가 빈 공간을 요소 간 비례 분배
  • Column vs LazyColumn: 3-10개 요소는 Column, 긴 목록은 LazyColumn
  • IntrinsicSize로 Column이 자식의 최소 측정에 맞게 높이 조정 가능
  • 권장: 각 요소에 padding 대신 요소 간 간격에 spacedBy 사용

턴키 방식의 모바일 애플리케이션을 개발해 드립니다

IT Sectr는 2017년부터 스타트업과 기업을 위한 iOS 및 Android 애플리케이션을 만듭니다. 저희가 상담해 드리고 최적의 솔루션을 제안하겠습니다.

프로젝트 논의

더 읽어보기