컨테이너 속성 설정

그리드 컨테이너 구성을 정의하여 다양한 화면 크기와 콘텐츠 유형에 반응하는 유연한 레이아웃을 만들 수 있습니다. 이 페이지에서는 다음 작업을 수행하는 방법을 설명합니다.

  • 그리드 정의: 행과 열의 기본 구조를 설정합니다.
  • 그리드에 항목 배치: 항목이 그리드 셀에 배치되는 방식과 흐름 방향을 변경하는 방법을 이해합니다.
  • 트랙 크기 관리: 고정, 비율, 유연한, 고유 크기 조정을 사용하여 트랙 크기를 설정합니다.
  • 간격 설정: 행과 열 사이의 "거터"를 관리합니다.

그리드 정의

그리드는 열과 행으로 구성됩니다. Grid 컴포저블에는 GridConfigurationScope 내에서 열과 행을 정의하는 람다를 허용하는 config 매개변수 가 있습니다. 다음 예에서는 3개의 행과 2개의 열이 있는 그리드를 정의합니다. 각각 Dp에 지정된 고정 크기가 있습니다.

Grid(
    config = {
        repeat(2) {
            column(160.dp)
        }
        repeat(3) {
            row(90.dp)
        }
    }
) {
}

그리드에 항목 배치

Gridcontent 람다의 UI 요소를 가져와 그리드 셀에 배치합니다. 행과 열을 명시적으로 정의했는지 여부와 관계없이 그리드는 항목을 배치합니다. 기본적으로 Grid는 행의 사용 가능한 그리드 셀에 UI 요소를 배치하려고 시도합니다. 이렇게 할 수 없는 경우 다음 행의 사용 가능한 그리드 셀에 배치합니다. 빈 셀이 없으면 Grid는 새 행을 만듭니다.

다음 예에서 그리드에는 6개의 그리드 셀이 있으며 각 셀에 카드를 배치합니다 (그림 1). 각 그리드 셀은 160dp x 90dp이므로 총 그리드 크기는 320dp x 270dp입니다.

Grid(
    config = {
        repeat(2) {
            column(160.dp)
        }
        repeat(3) {
            row(90.dp)
        }
    }
) {
    Card1()
    Card2()
    Card3()
    Card4()
    Card5()
    Card6()
}

3개의 행과 2개의 열이 있는 그리드에 6개의 카드가 배치되어 있습니다.
그림 1. 3개의 행과 2개의 열이 있는 그리드에 6개의 카드가 배치됩니다.

이 기본 동작을 열별로 채우도록 변경하려면 flow 속성을 GridFlow.Column으로 설정합니다.

Grid(
    config = {
        repeat(2) {
            column(160.dp)
        }
        repeat(3) {
            row(90.dp)
        }
        gap(8.dp)
        flow = GridFlow.Column // Grid tries to place items to fill the column
    },
) {
    Card1()
    Card2()
    Card3()
    Card4()
    Card5()
    Card6()
}

흐름 함수는 항목을 배치하는 방향을 변경합니다.
그림 2. GridFlow.Row (왼쪽) 및 GridFlow.Column (오른쪽)

트랙 크기 관리

행과 열을 통칭하여 그리드 트랙이라고 합니다. 다음 방법 중 하나를 사용하여 그리드 트랙의 크기를 지정할 수 있습니다.

  • 고정 (Dp): 특정 크기를 할당합니다 (예: column(180.dp)).
  • 비율 (Float): 0.0f에서 1.0f까지 사용 가능한 총 공간의 비율을 할당합니다 (예: 50%의 경우 row(0.5f)).
  • 유연한 (Fr): 고정 및 비율 트랙이 계산된 후 나머지 공간을 비례적으로 분배합니다. 예를 들어 두 행이 1.fr3.fr로 설정된 경우 후자는 나머지 높이의 75% 를 받습니다.
  • 고유: 트랙 내부의 콘텐츠를 기반으로 트랙 크기를 조정합니다. 자세한 내용은 고유하게 그리드 트랙 크기 결정을 참고하세요.

다음 예에서는 다양한 트랙 크기 조정 옵션을 사용하여 행 높이를 정의합니다.

Grid(
    config = {
        column(1f)

        row(100.dp)
        row(0.2f)
        row(1.fr)
        row(GridTrackSize.Auto)
    },
    modifier = Modifier.height(480.dp)
) {
    PastelRedCard("Fixed(100.dp)")
        PastelGreenCard("Percentage(0.2f)")
    PastelBlueCard("Flex(1.fr)")
        PastelYellowCard("Auto")

}

4가지 기본 트랙 크기 조정 옵션을 사용하여 정의된 행 높이
그림 3. Grid의 4가지 기본 트랙 크기 조정 옵션을 사용하여 정의된 행 높이

유연한 그리드 트랙의 최소 크기 설정

그리드 컨테이너에 남은 공간이 없으면 표준 유연한 트랙이 0.dp로 축소될 수 있습니다. 이를 방지하고 콘텐츠가 압축되지 않도록 하려면 GridTrackSize.MinMax 을 사용하여 트랙을 유연하게 유지하면서 명시적 최소 크기를 적용합니다.

다음 예에서는 첫 번째 행에 최소 100.dp를 할당합니다.

Grid(
    config = {
        column(1f)
        // The first row has a minimum height of 100.dp and can expand to 
        // the half of the remaining space.
        row(GridTrackSize.MinMax(100.dp, 1.fr))
        // The second row takes the half of the remaining space.
        row(1.fr)
        // The third row has a fixed height of 200.dp.
        row(200.dp)
    },
    modifier = Modifier.size(360.dp) // Total grid height is 360.dp
) {
    PastelRedCard("MinMax(100.dp, 1.fr)")
        PastelGreenCard("Flex(1.fr)")
    PastelBlueCard("Fixed(200.dp)")
}

4가지 기본 트랙 크기 조정 옵션을 사용하여 정의된 행 높이
그림 4. 첫 번째 행의 높이는 최소 100.dp입니다.

최소 그리드 트랙 크기를 설정하여 지연 목록 배치

표준 유연한 트랙은 하위 요소의 고유 크기를 자동으로 쿼리하여 기본 크기를 설정합니다. 그러나 Jetpack Compose는 SubcomposeLayout의 고유 크기 쿼리를 금지합니다. 이는 LazyColumnLazyRow과 같은 구성요소를 지원합니다.

표준 유연한 트랙 내에 지연 목록을 배치하면 IllegalStateException 비정상 종료가 발생합니다. 유연한 그리드 트랙 내에 지연 목록을 안전하게 배치하려면 명시적 최소 크기 (예: 0.dp)로 MinMax를 사용하여 고유 측정 패스를 우회합니다.

Grid(
    config = {
        column(1f)
        // The first row's height is determined by the height of the Text composable.
        row(GridTrackSize.Auto)
        // The second row occupies the remaining space, allowing the LazyColumn to scroll.
        row(GridTrackSize.MinMax(0.dp, 1.fr))

        gap(8.dp)
    },
    modifier = Modifier.size(width = 170.dp, height = 240.dp)
) {
    Text("Lazy column in a Grid")
    // The LazyColumn is placed in the second row, filling the remaining space.
    LazyColumn(verticalArrangement = Arrangement.spacedBy(4.dp)) {
        items(100) { number ->
            PastelGreenCard("Card $number")
        }
    }
}

4가지 기본 트랙 크기 조정 옵션을 사용하여 정의된 행 높이
그림 5. 그리드 셀의 LazyColumn

고유하게 그리드 트랙 크기 결정

레이아웃을 고정 컨테이너에 강제로 넣는 대신 콘텐츠에 맞게 조정하려면 고유 크기 조정Grid 에 사용할 수 있습니다. 그리드 트랙 크기는 다음 값으로 결정됩니다.

  • GridTrackSize.MaxContent: 콘텐츠의 최대 고유 크기를 사용합니다(예: 줄바꿈이 없는 텍스트 블록에서 텍스트의 전체 길이에 따라 너비가 결정됨).
  • GridTrackSize.MinContent: 콘텐츠의 최소 고유 크기를 사용합니다(예: 텍스트 블록에서 가장 긴 단일 단어에 따라 너비가 결정됨).
  • GridTrackSize.Auto: 사용 가능한 공간에 따라 조정되는 트랙에 유연한 크기를 사용합니다. 기본적으로 MaxContent와 같이 동작하지만 상위 컨테이너에 맞게 콘텐츠를 축소하고 줄바꿈합니다.

다음 예에서는 두 텍스트를 나란히 배치합니다. 첫 번째 텍스트의 열 크기는 텍스트를 표시하는 데 필요한 최소 너비에 따라 결정되고 두 번째 열 너비는 텍스트의 필요한 최대 너비에 따라 달라집니다.

Grid(
    config = {
        column(GridTrackSize.MinContent)
        column(GridTrackSize.MaxContent)
        row(1.0f)
    },
    modifier = Modifier.width(480.dp)
) {
    Text("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras imperdiet.")
    Text("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras imperdiet.")
}

열에 지정된 내장 크기입니다.
그림 5. 열에 지정된 고유 크기

행과 열 사이의 간격 설정

그리드 트랙의 크기가 조정되면, 그리드 간격을 수정하여 트랙 간의 간격을 세부적으로 조정할 수 있습니다. columnGap 함수로 열 간격을 지정하고 rowGap으로 행 간격을 지정할 수 있습니다. 다음 예에서는 각 행 사이에 16dp 간격이 있고 각 열 사이에 8dp 간격이 있습니다 (그림 5).

Grid(
    config = {
        repeat(2) {
            column(160.dp)
        }
        repeat(3) {
            row(90.dp)
        }
        rowGap(16.dp)
        columnGap(8.dp)
    }
) {
    Card1()
    Card2()
    Card3()
    Card4()
    Card5()
    Card6()
}

행과 열 사이의 간격입니다.
그림 6. 행과 열 사이의 간격

편의 함수 gap `gap`을 사용하여 동일한 열 및 행 크기의 간격을 정의하고 단일 함수를 사용하여 열 및 간격 크기를 별도로 정의할 수도 있습니다. 다음 코드는 그리드에 8dp 간격을 추가합니다.

Grid(
    config = {
        repeat(2) {
            column(160.dp)
        }
        repeat(3) {
            row(90.dp)
        }
        gap(8.dp) // Equivalent to columnGap(8.dp) and rowGap(8.dp)
    }
) {
    Card1()
    Card2()
    Card3()
    Card4()
    Card5()
    Card6()
}