Compose Grid List - LazyVerticalGrid, LazyHorizontalGrid로 격자형 리스트 구현

LazyVerticalGrid과 LazyHorizontalGrid란?

LazyVerticalGrid과 LazyHorizontalGrid는 각각 Jetpack Compose에서 제공하는 그리드 리스트 컴포넌트이다.

그러면 그리드 리스트란 무엇일까? 그리드(Grid)는 격자무늬라는 의미를 갖는다. 그래서 그리드 리스트란 격자 모양대로 여러 개의 행과 열을 갖는 리스트를 의미한다.


먼저 LazyColumn과 LazyRow를 보면, LazyColumn과 LazyRow 이 둘은 방향의 차이가 있을 뿐이지 똑같이 리스트를 구현하는 컴포넌트이다.

하지만 생각해보면 LazyColumn과 LazyRow은 행과 열 중 하나가 1로 고정된 채로 리스트를 구현하였다.

그렇다면 1로 고정되어 있던 행과 열의 개수를 변경하여 리스트를 나타내고 싶을 수 있다. 이럴 경우 사용할 수 있는 것이 그리드 리스트로, 고정되어 있던 행과 열의 개수를 지정하여 리스트를 구현할 수 있다.

가장 보편적인 예를 말하면 다수의 이미지를 보여주는 갤러리를 말할 수 있다.

그림1. 대표 예시 이미지


LazyVerticalGrid과 LazyHorizontalGrid 사용

먼저 LazyVerticalGrid과 LazyHorizontalGrid간 차이는 리스트 스크롤 방향이 각각 수직(세로), 수평(가로)이며

앞서 설명하였듯이 LazyVerticalGrid과 LazyHorizontalGrid는 LazyColumn과 LazyRow서 1로 고정되어 있었던 행과 열의 개수를 변경할 수 있을 뿐 그 외 것들은 기존 LazyColumn과 LazyRow와 동일하다.

그래서 리스트 아이템들을 나타내기 위해 사용하는 함수들도 동일하다.

단일 아이템을 나타내기 위해서는 item() 함수를, 다수의 아이템을 나타내기 위해서 items(), itemsIndexed() 함수를 사용하면 된다.

이와 관련된 자세한 내용은 이 글에서 확인할 수 있다.


그렇다면 지금까지 LazyVerticalGrid과 LazyHorizontalGrid가 무엇인지 알았다면 이젠 가장 중요한 고정되어 있던 행과 열의 개수를 어떤 방식으로 지정하느냐 이다.

Compose에서는 직접 행과 열의 개수를 지정하거나 최소 길이를 지정할 수 있도록 GridCells 클래스에서 다음과 같은 메서드를 제공한다.

  • Adaptive : 최소 길이 지정
  • Fixed : 개수 지정


각 메서드를 설명하기 앞서 먼저 각 리스트 아이템을 나타내는 컴포저블 함수를 보면 다음과 같다.

@Composable
fun ListGridItem(index: Int, text: String) {
val widths = listOf(150.dp, 200.dp, 250.dp)
val colors = listOf(Color(222, 193, 240, 255),
Color(221, 243, 181, 255),
Color(172, 215, 243, 255)
)
Column(
modifier = Modifier.width(widths.random()).height(100.dp).background(colors.random()),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
) {
Text(text = "$text $index")
}
}

각 항목들이 잘 구분되도록 배경색을 랜덤으로 지정하도록 하였으며

Adaptive가 어떤 방식으로 동작하는지 확인하기 위해서 widths로 정의한 길이들을 랜덤으로 지정하였다.



Adaptive(minSize)

LazyVerticalGrid를 사용하여 수직으로 스크롤이 되는 격자형 리스트를 구현하였다.

여기서 열의 개수는 Adaptive를 사용하여서 minSize(최소 길이)를 지정해 주었다.

여기서 최소 길이란 각 열에서 가져야만 하는 너비의 최소 길이를 의미한다. 즉, 200으로 지정하였을 때 각 열은 최소 200의 길이를 가져야 하며 나머지는 균등하게 나타나도록 조절이 된다.

그래서 ListGridItem 함수에서 랜덤으로 길이를 지정해 주었어도 그림2을 보면 동일한 길이를 갖는 것을 볼 수 있다.

LazyVerticalGrid(columns = GridCells.Adaptive(minSize = 200.dp)) {
itemsIndexed(sample) { index, text ->
ListGridItem(index, text)
}
}

그림2. minSize = 200

그림3. minSize = 300

반면 그림3을 보면 minSize가 300일 경우에는 각 행마다 1개의 열 만을 갖는 것을 볼 수 있다.

왜 그런 것이냐 하면 이것 경우도 동일한 방식에 의한 것이다.


최소 길이가 300이기 때문에 2개의 열이 오기 위해서는 전체 길이가 최소 600은 되어야 한다.

하지만 전체 길이가 600보다 작기 때문에 최소 길이를 충족하지 못하고 2개의 열을 나타낼 수 없기 때문에 1개의 열 만을 나타내게 된다.

이후 남은 길이만큼 1개의 열의 재분배를 하면 결국 리스트의 길이를 가득 채우는 한 열이 만들어지는 것이다.



Fixed(count)

LazyHorizontalGrid를 사용하여 수평으로 스크롤 되는 격자형 리스트를 구현한다.

Fixed 같은 경우에는 count(개수)를 지정해주는 식으로 한 열에서 보여주고 싶은 행의 개수를 지정하면 그만큼 행들을 자동으로 높이를 조절해서 나타낸다.

Adaptive에 비해 훨씬 직관적으로 사용할 수 있다.

LazyHorizontalGrid(rows = GridCells.Fixed(3)) {
items(50) { index ->
ListGridItem(index, "item")
}
}

그림4. Fixed로 행 개수 지정


참고

전체 코드 | Github



댓글

이 블로그의 인기 게시물

Compose Toast message - 토스트 메시지 사용

Compose DatePickerDialog - 날짜 선택 제한

Compose BottomBar transparent background - 모서리 둥글게