본문 바로가기
Android/Jetpack Compose Concepts

JETPACK COMPOSE: Column에 대해 알아보자

by 개발자J의일상 2022. 1. 13.
반응형

Column Coposable은 수직으로 배열된 형식으로 Composable collection을 표시하는 기능을 제공합니다.

여기서 Composable은 동시에 하나씩 차례로 표시됩니다.

 

Column을 선언할 때 생성자(constructor)가 취할 수 있는네 가지 인수(argument)가 있습니다.

@Composable
inline fun Column(
    modifier: Modifier = Modifier,
    verticalArrangement: Arrangement.Vertical = Arrangement.Top,
    horizontalAlignment: Alignment.Horizontal = Alignment.Start,
    children: @Composable ColumnScope.() -> Unit
)
  • modifier : Column에 적용할 modifier
  • verticalArrangement : 세로축에 자식을 어떻게 배열해야 하는지
  • horizontalAlignment : 가로 축에서 자식을 정렬하는 방법
  • children : Column 내부에 표시될 자식 (required)

DECLARING CHILDREN

Column을 선언할 때 children이 필요합니다. children 인수에 대해 어떠한 composable collection도 선언할 수 있습니다.

@Composable
fun MyApp() {
    Surface()
    {
        Column(modifier = Modifier.background(color=Color(0xFF4666d0)))
        {
            Text(text = "Hello")
            Text(text = "World")
        }
    }
}

children들이 세로 순서로 표시됩니다.

여기에서 Column이 포함하는 자식의 크기를 래핑하고 있음을 알 수 있습니다. children인 text의 크기만큼만 background color가 있는 것을 볼 수 있습니다.

COLUMN MODIFIERS

modifier 매개변수를 사용하여 Column에 modifer를 적용할 수 있습니다.

여기에서 우리는 Column composable에 의해 특별히 정의된 modifier를 추가하여 다른 composable에 적용할 전역 modifier를 사용할 수 있습니다.

composable에 children이 추가되면 Column 범위에 있는 것으로 레이블이 지정됩니다.

이렇게 하면 Column과 함께 사용하도록 정의된 modifier에 접근할 수 있습니다.

 

예를 들어 Column의 children의 width와 height를 감싸므로 Column이 화면 내에서 사용 가능한 공간을 채우도록 합시다.

Modifier.fillMaxSize()를 사용하면 됩니다.

@Composable
fun MyApp() {
    Surface()
    {
        Column(modifier = Modifier
            .fillMaxSize()
            .background(color=Color(0xFF4666d0)))
        {
            Text(text = "Hello")
            Text(text = "World")
        }
    }
}

이번에는 모든 화면을 파란색이 다 덮은 것을 볼 수 있습니다. Column이 화면에서 사용 가능한 모든 공간을 다 채웠기 때문입니다.

ALIGN MODIFIER

이러한 Column modifier 중 첫 번째는 align이며 Column 내부의 각 children에 align을 적용하는 데 사용할 수 있습니다.

Column 자체가 children의 세로 layout을 처리하기 때문에 align을 사용하면 각 children행에서 사용할 수 있는 가로 공간을 어느 정도 제어할 수 있습니다.

Align은 children구성 요소의 width보다 더 넓은 공간이 있는 경우에만 유효합니다. 그렇지 않으면 align이 효과가 없습니다.

사용 가능한 modifier를 사용하여 align을 설정할 수 있습니다.

fun Modifier. align(align: Alignment.Horizontal)

여기에서 설정한 align은 직접 설정된 하위 항목에 적용됩니다. 

이를 통해 Column 내부의 children정렬을 각각 제어할 수 있습니다.

기본적으로 정렬은 Alignment.Start로 설정됩니다. 기본값이므로 설정할 필요가 없습니다.

@Composable
fun MyApp() {
    Surface()
    {
        Column(modifier = Modifier
            .fillMaxSize()
            .background(color=Color(0xFF4666d0)))
        {
            Text(text = "First item",
                modifier = Modifier.align(alignment = Alignment.Start)
            )
            Text(text = "Second item")
        }
    }
}

 

아래와 같이 align이 적용된 children는 두 번째 children의 기본 정렬과 차이가 없는 것을 확인할 수 있습니다.

 

적용된 기본 정렬과 다른 정렬을 원하면 사용 가능한 다른 두 값 중 하나를 사용할 수 있습니다.

첫 번째는 사용 가능한 공간(CenterHorizontally)에서 children를 수평으로 가운데에 맞추는 데 사용됩니다.

@Composable
fun MyApp() {
    Surface()
    {
        Column(modifier = Modifier
            .fillMaxSize()
            .background(color=Color(0xFF4666d0)))
        {
            Text(text = "First item",
                modifier = Modifier.align(alignment = Alignment.CenterHorizontally)
            )
            Text(text = "Second item")
        }
    }
}

 

드디어 바뀐 것을 확인할 수 있습니다! 첫 번째 children가 뷰의 중앙에 온 것을 볼 수 있습니다. 두 번째 children는 기본 정렬이 적용된 상태로 그대로 유지됩니다.

 

children를 가로로 입력하는 것 외에도 Column width의 끝에 children를 정렬할 수도 있습니다. Alignment.End

@Composable
fun MyApp() {
    Surface()
    {
        Column(modifier = Modifier
            .fillMaxSize()
            .background(color=Color(0xFF4666d0)))
        {
            Text(text = "First item",
                modifier = Modifier.align(alignment = Alignment.End)
            )
            Text(text = "Second item")
        }
    }
}

 

첫 번째 children가 뷰의 끝에 정렬된 것을 볼 수 있습니다.

 

WEIGHT MODIFIER

Column 내에 child composable들을 배치할 때 고정 height를 정의하지 않고도 각 children가 차지하는 공간을 제어할 수 있습니다. 

이러한 경우 weight modifier를 사용하여 유동적이고 동적인 layout을 만들 수 있습니다.

weight modifier도 Column 범위의 일부입니다.

weight는 composable이 얻어야 하는 사용 가능한 height를 정의합니다.

따라서 컨테이너 안에 3개의 composable이 있다고 가정해 봅시다.

그중 두 개는 가중치가 3이고 세 번째 가중치가 2입니다. 그럼 총합은 8이 됩니다.

사용 가능한 height를 8로 나누고 해당 weight에 따라 child들에게 분배합니다.

 

weight modifier는 2개의 인수를 받습니다.

  • weight - composable에 적용할 가중치
  • fill - composable의 content가 사용 가능한 전체 height를 채워야 하는지 여부입니다. 기본값은 true이지만 false로 설정해도 weight 공간이 다른 child에게 재분배되지 않습니다. 대신 Column height에서 제거됩니다.
fun Modifier.weight(
    @FloatRange(from = 0.0, to = 3.4e38, fromInclusive = false)
    weight: Float,
    fill: Boolean = true
)

weight modifier를 적용하지 않으면 각 children은 composable의 height 제약 조건만큼의 공간을 차지합니다.

 

아까의 예제를 다시 가져왔습니다.

배경이 없어서 좀 Text의 height를 확인하기 힘든 것 같아서 배경색을 추가해봤습니다. Modifier.background()

@Composable
fun MyApp() {
    Surface()
    {
        Column(modifier = Modifier
            .fillMaxSize()
            .background(color=Color(0xFF4666d0)))
        {
            Text(text = "First item",
                modifier=Modifier
                    .background(color=Color.Yellow)
            )
            Text(text = "Second item",
                modifier=Modifier
                    .background(color=Color.Green)
            )
        }
    }
}

 

각 children가 height 제약 조건만큼의 공간만 차지한 것을 볼 수 있습니다.

 

 

이제 weight를 한번 줘봅시다! Modifier.weight()를 children인 Text에 추가하면 됩니다.

@Composable
fun MyApp() {
    Surface()
    {
        Column(modifier = Modifier
            .fillMaxSize()
            .background(color=Color(0xFF4666d0)))
        {
            Text(text = "First item",
                modifier=Modifier.weight(1f)
                    .background(color=Color.Yellow)
            )
            Text(text = "Second item",
                modifier=Modifier.weight(1f)
                    .background(color=Color.Green)
            )
        }
    }
}

 

두 children가 1:1 비율로 height가 꽉 찬 것을 볼 수 있습니다. 

 

 

children 중 하나에 더 큰 weight를 할당하면 다른 children보다 더 많은 컨테이너 height가 주어지게 됩니다.

@Composable
fun MyApp() {
    Surface()
    {
        Column(modifier = Modifier
            .fillMaxSize()
            .background(color=Color(0xFF4666d0)))
        {
            Text(text = "First item",
                modifier=Modifier.weight(2f)
                    .background(color=Color.Yellow)
            )
            Text(text = "Second item",
                modifier=Modifier.weight(1f)
                    .background(color=Color.Green)
            )
        }
    }
}

2/3이 First item에 할당된 것을 확인할 수 있습니다.

 

어떤 경우에는 children의 weight를 주고 싶지만 children가 그 전체 면적을 소비하지 않도록 할 수 있습니다. 이는 다른 children에게 사용할 수 없는 weight가 됩니다. 이러한 경우 weight modifier에 대한 fill 인수를 사용하면 됩니다.

이것은 다른 children가 이 height를 사용할 수 없으며 지정된 children가 height를 계산할 때 전체 weight를 사용할 필요가 없다는 것을 의미합니다. 

이 경우 빈 공간은 기둥 하단에 추가됩니다.

@Composable
fun MyApp() {
    Surface()
    {
        Column(modifier = Modifier
            .fillMaxSize()
            .background(color=Color(0xFF4666d0)))
        {
            Text(text = "First item",
                modifier=Modifier.weight(2f, fill = false)
                    .background(color=Color.Yellow)
            )
            Text(text = "Second item",
                modifier=Modifier.weight(1f)
                    .background(color=Color.Green)
            )
        }
    }
}

First item의 height는 원래대로 돌아왔고 Second item도 아까 봤던 1/3 weight와 동일한 height만 차지하는 것을 볼 수 있습니다. bottom of the Column의 space가 unoccupied space가 되었습니다.

 

ARRANGING CHILDREN

Column의 children경우 verticalArrangement 매개변수를 사용하여 세로축에 정렬할 수 있습니다.

이를 통해 사용 가능한 vertical 공간이 주어지면 composable을 배치하는 방법을 선언할 수 있습니다.

Column내에 사용 가능한 추가 공간이 있으면 children을 Column내의 그룹으로 세로로 배치할 수 있습니다.

Column에 children을 추가할 때 기본적으로 Column의 맨 위에 정렬되도록 배치됩니다.

이 배열 속성은 다음 중 하나로 설정할 수 있습니다.

  • Top - Column의 맨 위에 children 정렬
  • Center - Column의 중심에 children 정렬
  • Bottom - Column의 맨 아래 children 정렬
  • Space Around - Column 내에서 children을 고르게 배포합니다. 첫 번째 children 앞과 마지막 children 뒤에 공백을 추가할 뿐만 아니라 각 연속되는 children 사이에도 공백의 절반이 추가됩니다.
  • Space Between - 첫 번째 children 앞이나 마지막 children 뒤에 공백을 추가하지 않고 Column 안에 children을 고르게 분배합니다.
  • Space Evenly - Column내에서 children을 고르게 분배하고 첫 번째 children 앞과 마지막 children 뒤에 공백을 추가합니다.

기본적으로 Column은 Top Arrangement를 사용하여 children을 배치합니다.

수동으로 설정할 필요는 없지만 다음을 수행하는 것과 동일합니다.

@Composable
fun MyApp() {
    Surface()
    {
        Column(modifier = Modifier
            .fillMaxSize()
            .background(color=Color(0xFF4666d0)),
            verticalArrangement = Arrangement.Top)
        {
            Text(text = "First item",
                modifier=Modifier
                    .background(color=Color.Yellow)
            )
            Text(text = "Second item",
                modifier=Modifier
                    .background(color=Color.Green)
            )
        }
    }
}

verticalArrangement = Arrangement.Top을 수동으로 설정하여도 기존과 동일한 결과를 얻게 되는 것을 볼 수 있습니다.

 

Column 내에서 수직으로 children을 배치하려면 Arrangement.Center를 사용할 수 있습니다.

@Composable
fun MyApp() {
    Surface()
    {
        Column(modifier = Modifier
            .fillMaxSize()
            .background(color=Color(0xFF4666d0)),
            verticalArrangement = Arrangement.Center)
        {
            Text(text = "First item",
                modifier=Modifier
                    .background(color=Color.Yellow)
            )
            Text(text = "Second item",
                modifier=Modifier
                    .background(color=Color.Green)
            )
        }
    }
}

verticalArrangement = Arrangement.Center를 설정하면 세로축으로 봤을 때 Center에 children들이 이동한 것을 확인할 수 있습니다.

Column의 맨 아래에 children을 배치하려면 Arrangement.Bottom을 사용할 수 있습니다.

@Composable
fun MyApp() {
    Surface()
    {
        Column(modifier = Modifier
            .fillMaxSize()
            .background(color=Color(0xFF4666d0)),
            verticalArrangement = Arrangement.Bottom)
        {
            Text(text = "First item",
                modifier=Modifier
                    .background(color=Color.Yellow)
            )
            Text(text = "Second item",
                modifier=Modifier
                    .background(color=Color.Green)
            )
        }
    }
}

 

verticalArrangement = Arrangement.Bottom을 설정하면 세로축을 기준으로 아래에 children들이 이동한 것을 볼 수 있습니다.

어떤 경우에는 세로축을 가로질러 children을 고르게 분포시키고 싶을 수도 있습니다.

이러한 경우 Arrangement.SpaceEvenly를 사용할 수 있습니다.

이렇게 하면 Column 내에서 사용 가능한 공간을 가져와 각 children 사이에 배치하는데, 첫 번째 children 앞과 마지막 children 뒤도 공간이 배치됩니다.

@Composable
fun MyApp() {
    Surface()
    {
        Column(modifier = Modifier
            .fillMaxSize()
            .background(color=Color(0xFF4666d0)),
            verticalArrangement = Arrangement.SpaceEvenly)
        {
            Text(text = "First item",
                modifier=Modifier
                    .background(color=Color.Yellow)
            )
            Text(text = "Second item",
                modifier=Modifier
                    .background(color=Color.Green)
            )
        }
    }
}

유사하게, 우리는 수직 축을 가로질러 children을 배치할 수 있으며, 첫 번째 children 앞이나 마지막 children 뒤에는 공간을 배치하지 않고 각 children 사이에 사용 가능한 공간을 분배할 수 있습니다.

@Composable
fun MyApp() {
    Surface()
    {
        Column(modifier = Modifier
            .fillMaxSize()
            .background(color=Color(0xFF4666d0)),
            verticalArrangement = Arrangement.SpaceBetween)
        {
            Text(text = "First item",
                modifier=Modifier
                    .background(color=Color.Yellow)
            )
            Text(text = "Second item",
                modifier=Modifier
                    .background(color=Color.Green)
            )
        }
    }
}

마지막으로 SpaceAround는 children사이의 간격에 공간을 분배하는 약간 다른 방법을 제공합니다.

이것은 첫 번째 자식 앞과 마지막 자식 뒤에 공간이 분산되는 SpaceEvenly와 매우 유사합니다.

그러나 각 children 사이에는 공간을 추가하는 경우 각 children 사이에 공간의 절반만 할당됩니다.

@Composable
fun MyApp() {
    Surface()
    {
        Column(modifier = Modifier
            .fillMaxSize()
            .background(color=Color(0xFF4666d0)),
            verticalArrangement = Arrangement.SpaceAround)
        {
            Text(text = "First item",
                modifier=Modifier
                    .background(color=Color.Yellow)
            )
            Text(text = "Second item",
                modifier=Modifier
                    .background(color=Color.Green)
            )
        }
    }
}

 

좌 : Arrangement.SpaceAround, 우 : Arrangement.SpaceEvenly

CHILD ALIGNMENT

Column arrangement을 사용하면 세로 축을 따라 children을 구성할 수 있고 align modifier를 사용하여 개별 children을 수평으로 정렬할 수 있지만 수평 축에 children을 집합적으로 그룹으로 배치할 수도 있습니다.

이를 위해 Column에 대해 horizontalAlignment 매개변수를 사용할 수 있습니다.

이를 통해 모든 Column childen을 수평 축에 배치할 수 있습니다.

 

horizontalAlignment 매개변수는 다음 세 가지 값을 할당할 수 있습니다.

  • Start - 가로 축의 시작 부분에 children 정렬
  • CenterHorizontally - 가로 축의 중심에 children 정렬
  • End - 가로 축의 끝에 children 정렬

기본적으로 Alignment.Start 값이 사용됩니다.

수동으로 설정할 필요는 없지만 아래와 동일하게 수행됩니다. 처음과 변화가 없는 것을 확인할 수 있습니다.

@Composable
fun MyApp() {
    Surface()
    {
        Column(modifier = Modifier
            .fillMaxSize()
            .background(color=Color(0xFF4666d0)),
            horizontalAlignment = Alignment.Start)
        {
            Text(text = "First item",
                modifier=Modifier
                    .background(color=Color.Yellow)
            )
            Text(text = "Second item",
                modifier=Modifier
                    .background(color=Color.Green)
            )
        }
    }
}

수평 축의 중앙에 children 그룹을 정렬하려면 Alignment.CenterHorizontally를 horizontalAlignment의 값으로 넣어주면 됩니다.

@Composable
fun MyApp() {
    Surface()
    {
        Column(modifier = Modifier
            .fillMaxSize()
            .background(color=Color(0xFF4666d0)),
            horizontalAlignment = Alignment.CenterHorizontally)
        {
            Text(text = "First item",
                modifier=Modifier
                    .background(color=Color.Yellow)
            )
            Text(text = "Second item",
                modifier=Modifier
                    .background(color=Color.Green)
            )
        }
    }
}

 

마지막으로 Alignment.End를 사용하여 가로축에서 Column의 맨 끝에 children 그룹을 배치할 수 있습니다.

 

@Composable
fun MyApp() {
    Surface()
    {
        Column(modifier = Modifier
            .fillMaxSize()
            .background(color=Color(0xFF4666d0)),
            horizontalAlignment = Alignment.End)
        {
            Text(text = "First item",
                modifier=Modifier
                    .background(color=Color.Yellow)
            )
            Text(text = "Second item",
                modifier=Modifier
                    .background(color=Color.Green)
            )
        }
    }
}

 

끝쪽에 글자들이 정렬된 것을 확인할 수 있습니다.

 

 

이것으로 Column에 대해 모두 살펴보았습니다.

 

감사합니다.

 

https://joebirch.co/android/exploring-jetpack-compose-column/
300x250

댓글