Study Record

[Flutter] GridView 본문

Flutter/widget_scrollView

[Flutter] GridView

초코초코초코 2023. 3. 8. 00:40
728x90

🎁 GridView

행과 열이 복잡한 리스트 뷰를 만들 수 있다.

 

 

😶 GridView.count

일반적으로 GridView 를 사용하는 방법이다. crossAxisCount 로 가로로 몇 줄로 넣을지 결정한다. crossAxisSpacing 으로 가로 사이의 간격을 mainAxisSpacing 으로 세로 사이의 간격을 정한다. children 으로 그리드뷰에 들어갈 항목을 정한다. children 에 위젯이 100개면 실행과 동시에 100개가 한 번에 생성된다. 따라서 개수가 많으면 비효율적일 수 있다.

GridView.count(
  // 가로로 몇개를 넣을래?
  crossAxisCount: 2,
  // 가로끼리의 간격
  crossAxisSpacing: 12.0,
  // 세로(위, 아래)끼리의 간격
  mainAxisSpacing: 6.0,
  children: List.generate(
    100,
    (index) => Container(
      color: Colors.black,
      child: Center(
        child: Text(
          "$index",
          style: TextStyle(color: Colors.white),
        ),
      ),
    ),
  ),
),

 

 

 

😶 GridView.builder

builder 는 gridDelegate 를 넣어줘야 하는데 SliverGridDelegateWithFixedCrossAxisCount() 와 SliverGridDelegateWithMaxCrossAxisExtent() 둘 중 하나를 선택할 수 있다. builder 로 생성하면 한 번에 위젯들이 생성되지 않고 화면에 보이는 항목들을 기준으로 생성하고 유지된다.

 

 

SliverGridDelegateWithFixedCrossAxisCount()

이름에서도 그렇듯 crossAxisCount 값을 꼭 설정해줘야 한다. GridView.count 에서와 같이  crossAxisCount 로 가로로 몇 줄로 넣을지 결정한다. crossAxisSpacing 으로 가로 사이의 간격을 mainAxisSpacing 으로 세로 사이의 간격을 정한다. count 는 children 으로 항목들을 정했다면 여기선 itemBuilder 로 정한다.

GridView.builder(
  itemCount: 20,
  // count 에서와 동일
  gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
    crossAxisCount: 2,
    crossAxisSpacing: 12.0,
    mainAxisSpacing: 12.0,
  ),
  itemBuilder: (context, index) {
    return Container(
      color: Colors.black,
      child: Center(
        child: Text("$index", style: TextStyle(color: Colors.white))),
    );
  },
);

 

 

SliverGridDelegateWithMaxCrossAxisExtent()

이름에서도 그렇듯 maxCrossAxisExtent 가 꼭 들어가야 한다. crossAxisSpacing 과 mainAxisSpacing 은 똑같이 가로 사이 간격, 세로 사이 간격을 뜻하고 maxCrossAxisExtent 는 교차 축에 있는 타일의 최대 범위로 예를 들어, 세로 스크롤(Axis.vertical), width = 500, maxCrossAxisExtent = 150 이면 각 125씩 가로로 4줄씩 배치한다.

GridView.builder(
  itemCount: 20,
  gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
    maxCrossAxisExtent: 200,
    crossAxisSpacing: 12.0,
    mainAxisSpacing: 12.0,
  ),
  itemBuilder: (context, index) {
    return Container(
      color: Colors.green,
      child: Center(
        child: Text("$index", style: TextStyle(color: Colors.white))),
    );
  },
);

 

 

🎁 GridView parameter

위에서 소개한 2가지 생성 방법에서 모두 적용할 수 있는 다른 파라미터에 대해 소개하자면 다음과 같다.

 

 

😶 가로 스크롤 vs 세로 스크롤(default)

scrollDirection 인자로 세로 스크롤(Axis.vertical), 가로 스크롤(Axis.horizontal)을 정할 수 있다. 세로 스크롤일 때는 세로와 관련된 위젯(ex. Column) 가로 스크롤일때는 가로와 관련된 위젯(ex. Row)을 사용해야 한다. 기본 값은 Axis.vertical 이다.

GridView.count(
  scrollDirection: Axis.horizontal,
  scrollDirection: Axis.vertical,
  ...
);

 

 

😶 키보드 컨트롤

keyboardDismissBehavior 인자를 사용하면 SingleChildScrollView 에 TextField 와 같이 입력 폼이 포함될 때, 사용자가 TextField 를 클릭 시 키보드가 올라왔을 때 스크롤 시 키보드가 자동으로 내려갈지(manual) 아니면 온전히 사용자에 맡길지(스크롤 시 자동으로 키보드가 내려가지 않음, onDrag) 정할 수 있다.

GridView(
  keyboardDismissBehavior: ScrollViewKeyboardDismissBehavior.manual  
  keyboardDismissBehavior: ScrollViewKeyboardDismissBehavior.onDrag
  ...
);

 

 

😶 스크롤 모양

physics 인자를 사용하면 스크롤 모양을 설정할 수 있다.

인자(physics) 설명
NeverScrollableScrollPhysics 사용자가 스크롤 불가능하다.
AlwaysScrollableScrollPhysics 항상 사용자가 스크롤을 가능하게 하고 스크롤 모양은 기종 기본값을 따른다.
BouncingScrollPhysics IOS 기본 스크롤 모양으로, 튕기는 모양이다.
ClampingScrollPhysics AOS 기본 스크롤 모양이다. 
PageScrollPhysics 페이지 단위로 스크롤할 수 있다.
GridView(
  physics: AlwaysScrollableScrollPhysics(),
  ...
);

 

 

+ BouncingScrollPhysics 가 적용된 상태에서 위젯이 화면 크기보다 작을 때 스크롤 시 잘려 보일 수 있다. clipBehavior 를 Clip.none 로 하면 위젯이 잘리지 않으면서 튕기는 스크롤 모양이 된다.

GridView(
  physics: AlwaysScrollableScrollPhysics(),
  clipBehavior: Clip.none,
  ...
);
728x90