GridView class
스크롤 가능한 2D 위젯 배열입니다.
공식 문서 코드
UI를 구성하다 보면 행과 열이 복잡한 형태의 레이아웃으로 구성될 때가 있는데 이럴 때 레이아웃 그리드로 만든다면 아주 빠르고 쉽게 만들 수 있을 것이다. 그리고 Flutter에는 그리드를 쉽게 만들 수 있도록 도와주는 GridView위젯이 있다.
이 GridView는 격자 형태의 스크롤 가능한 위젯을 만들 때 사용하는 매우 유용한 위젯으로 주로 일정한 간격으로 정렬된 이미지 목록이나 카드 등의 UI를 만들 때 사용된다. 바로 알아보자.
하위 속성
| 속성명 | 타입 | 기본값 | 설명 |
| gridDelegate | SliverGridDelegate | – | 그리드의 열 수, 간격, 비율 등을 정의하는 레이아웃 구성 규칙 |
| childrenDelegate | SliverChildDelegate | – | 그리드에 표시될 위젯 목록을 제공 |
| scrollDirection | Axis | Axis.vertical | 스크롤 방향 설정 (세로 또는 가로) |
| reverse | bool | false | 스크롤 방향을 반대로 설정할지 여부 |
| controller | ScrollController? | null | 스크롤을 제어할 수 있는 컨트롤러 |
| primary | bool? | null | 스크롤 뷰가 기본(primary)인지 여부 |
| physics | ScrollPhysics? | null | 스크롤 동작 방식 정의 |
| shrinkWrap | bool | false | 내용 크기만큼만 뷰를 축소할지 여부 |
| padding | EdgeInsetsGeometry? | null | 내부 위젯과의 여백 설정 |
| cacheExtent | double? | null | 스크롤 외 영역에서 캐시될 범위 |
| semanticChildCount | int? | null | 접근성을 위한 자식 수 지정 |
| clipBehavior | Clip | Clip.hardEdge | 자식이 부모를 벗어났을 때의 클리핑 방식 |
| keyboardDismissBehavior | ScrollViewKeyboardDismissBehavior | manual | 스크롤 시 키보드를 닫는 방식 설정 |
기본적으로 GridView위젯을 사용할 땐 이 위젯 자체만으로 사용하는 경우는 드물고 생성자를 붙여서 사용하게 된다. 한번 생성자들을 알아보자.
GridView.count()
사용하기 위해선 우선 그리드에 넣고자 하는 것들을 나열해줘야 한다. children은 List<Widget>타입이기 때문에 자신이 배치하고 싶은 만큼 위젯들을 배치해 주면 된다.
GridView.count(
children: [],
)
그다음에는 필수 파라미터인 crossAxisCount에 값을 넣어줘야 한다.
이 파라미터는 그리드에 넣을 항목 수를 조절해 주는 파라미터로 int타입을 갖고 있어 정수를 넣어주면 되는데 1을 넣어주면 일반적인 ListView와 다를 바가 없이 동작하지만 2 이상의 값을 넣어주게 되면 그 입력한 값만큼의 그리드 배열이 생성되게 된다.
crossAxisCount: 5,

이렇게 crossAxisCount를 5로 해두니 행에 5개의 위젯들이 배치되고 그다음 위젯은 다음칸으로 넘어가서 우리가 원하는 그리드의 형태로 잘 배치되는 것을 볼 수 있다.
근데 지금 이 상태로는 위젯들의 간격이 없어 너무 숨 막히는 상황인데 이럴 때 mainAxisSpacing 파라미터를 사용하여 행 사이의 수평 공간을 띄워줄 수 있다.
mainAxisSpacing: 10,

여기다가 crossAxisSpacing 파라미터를 사용해 주면 이번에는 사이의 수직 공간을 띄워줄 수 있게 된다.
crossAxisSpacing: 10,

그런데 한 가지 의문이 드는 것이 있다. 안에 배치되는 위젯의 크기는 어떻게 정하는가에 대한 것이다.
일단 안에 배치되는 위젯에 직접적으로 사이즈를 먹여서 조정하는 것은 불가능하다.
이 GridView.count의 자식들의 크기는 오로지 부모의 크기로만 결정되게 되는데 여기서 자식 위젯들의 크기를 변경하고 싶다면
자식 위젯들의 비율 값을 조정할 수 있는 childAspecRatio파라미터를 사용해 주면 된다.
childAspectRatio: 1.5,
childAspecRatio의 기본값은 1.0으로 정사각형의 형태인데 여기에서 값을 증가시키면 가로비가 늘어나면서 아래와 같은 형태가 된다.

반대로 값을 감소시키면 세로비가 늘어나면서 아래와 같은 형태로 된다.
childAspectRatio: 0.7,

지금까지 .count 생성자에 대해서 알아봤으니 이번에는 .builder 생성자를 사용해 보자.
GridView.builder()
이 빌더를 사용하기 위해선 먼저 필수 파라미터를 사용해줘야 하는데 그 필수 파라미터는 gridDelegate 되시겠다.
이제 이 파라미터 안에는 어떠한 값을 넣어야 하냐면 타입 그대로 SliverGridDelegateWithFixedCrossAxisCount 위젯을 넣어주면 된다.
그리고 이제 이 위젯의 파라미터로는 아까 위에서 했던 것처럼 crossAxisCount값을 설정해 주면 된다.
GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 4,
),
)
GridView.count()에서 파라미터로 위치해 있던 자식들의 속성과 관련된 모든 것들이 다 SliverGridDelegateWithFixedCrossAxisCount 위젯 안으로 넘어갔다고 생각하면 된다.
이제 여기 안에서 행과 열에 크기를 먹여 줄 수 있고 아까처럼 비율을 조절해 줄 수도 있다.
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
childAspectRatio: 0.7,
crossAxisCount: 4,
crossAxisSpacing: 10,
mainAxisSpacing: 10,
)
이제 다시 GridView.builder로 돌아와서 당연히 빌더 함수인만큼 itemBuilder 파라미터도 필수로 사용해줘야 한다.
이건 우리가 흔히 ListView.builder를 사용할 때처럼 그대로 사용해 주면 된다.
itemBuilder: (context, index) {
return Container(
decoration: BoxDecoration(
color: Colors.blue,
borderRadius: BorderRadius.all(Radius.circular(4)),
),
);
}
이렇게 itemBuilder 작성을 완료했다면 마지막으로 빌드될 아이템의 수들을 itemCount 파라미터에 입력해 주면 된다.
GridView.builder(
itemCount: 40,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
childAspectRatio: 0.7,
crossAxisCount: 4,
crossAxisSpacing: 10,
mainAxisSpacing: 10,
),
itemBuilder: (context, index) {
return Container(
decoration: BoxDecoration(
color: Colors.blue,
borderRadius: BorderRadius.all(Radius.circular(4)),
),
);
},
)

이제 이렇게 하면 스크롤이 되는 그리드가 완성이 되게 된다.
또한 여기서 scrollDirection 파라미터를 사용하면 LsitView.builder 처럼 스크롤 되는 방향을 바꿔 줄 수 있게 된다.
scrollDirection: Axis.horizontal,
위의 다트 패드를 실행해 보자. crossAxisSpacing값과 mainAxisSpacing의 값을 슬라이더로 조절해 볼 수 있다.
암튼 이렇게 GridView.builder 에 대해서 알아보았는데 사실 생성자가 몇 개 더 있다만 그냥 count랑 builder만 소개하기로 했다. 도움이 되었길 바라며 마치겠다.