화면에 grid 형태로 widget들을 배치할 수 있도록하고, listView와 마찬가지로 스크롤 기능이 제공된다.
- children의 사이즈와 포지션을 컨트롤하고, 두 가지 종류가 있다.
1. SliverGridDelegateWithFixedCrossAxisCount
몇 개를 배치할지 결정한다.
crossAxisCount : crossAxis 방향으로 몇개의 grid를 배치할 것인지 결정
crossAxisSpacing : 그리드 사이의 좌우 간격
mainAxisSpacing : 그리드 사이의 수직 간격
childAspectRatio : child의 가로 세로 비율
2. SliverGridDelegateWithMaxCrossAxisExtent
기본적인 reponsiveness를 제공해준다. 반응형으로 구현하고 싶을때 사용할 수 있다.
maxCrossAxisExtent 와 기기의 width를 이용하여 crossAxis으로 grid가 몇개가 들어갈지 지정한다.
maxCrossAxisExtent : child에게 부여할 최대 width 지정
crossAxisSpacing : 그리드 사이의 좌우 간격
mainAxisSpacing : 그리드 사이의 수직 간격
childAspectRatio : child의 가로 세로 비율
먼저 list generate function을 이용해서 30개의 list 아이템을 생성합니다.
final List<String> _items = List.generate(30, (index) => 'Item ${index + 1}');
GridView.builder를 이용해서 위에서 만든 item list를 렌더링합니다.
GridView.builder(
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
mainAxisSpacing: 10,
crossAxisSpacing: 6,
childAspectRatio: 1 / 2,
),
itemCount: _items.length,
itemBuilder: (context, index) => Card(
margin: const EdgeInsets.all(8),
elevation: 8,
child: GridTile(
header: GridTileBar(
backgroundColor: Colors.black26,
title: const Text('header'),
subtitle: Text('Item ${_items[index].split(' ')[1]}'),
),
footer: GridTileBar(
backgroundColor: Colors.black38,
title: const Text('footer'),
subtitle: Text('Item ${_items[index].split(' ')[1]}'),
),
child: Center(
child: Text(
_items[index],
style: const TextStyle(fontSize: 16),
),
),
),
),
)
MediaQuery.of(context).orientation을 이용해서 화면을 가로방향으로 회전하는 경우에는 다른 배열로 보이도록 구현할 수 있습니다.
Widget build(BuildContext context) {
var orientation = MediaQuery.of(context).orientation;
return Scaffold(
appBar: AppBar(
title: const Text('GridView Widget'),
),
body: GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: orientation == Orientation.portrait ? 2 : 3,
mainAxisSpacing: 10,
crossAxisSpacing: 6,
childAspectRatio: 1 / 2,
),
itemCount: _items.length,
itemBuilder: _buildItem,
),
);
}