본문 바로가기
프로그래밍/Flutter

[Flutter Layout] 14. 플러터 갤러리 만들기(using GirdView)

by 신나요 2022. 4. 15.

GridView에 대해 알아보고, GirdView를 이용해서 갤러리를 만들어 보도록 하겠습니다. 전체 소스코드는 하단에 첨부되어있습니다.

 

다음 내용을 다루고 있습니다.

  1. GridView란
  2. GridView 위젯 사용법
  3. GridView로 갤러리 만들기

GirdView 란

GridView는 스크롤 가능한 2D 위젯 배열입니다. 여기서 핵심 개념은 GridView가 스크롤 가능하고 2차원이라는 것입니다. 즉 스크롤 가능한 테이블입니다. ListView와 마찬가지로 가로 또는 세로로 스크롤할 수 있습니다. GirdView에서는 여러 가지 사례를 다루는 몇 가지 생성자가 있습니다. 생성자의 자세한 내용은 아래 공식 문서를 확인해 주세요.

https://api.flutter.dev/flutter/widgets/GridView-class.html

이번 포스트에서는 그리드가 화면에 표시할 항목 수를 알고 있을 때 사용할 수 있는 GridView.count 생성자에 대해 얘기해 보도록 하겠습니다.


GridView 위젯 사용하기

갤러리를 만들기 전에 간단히 GridView 위젯을 사용해 보겠습니다. 코드로 돌아가서 홈 클래스의 빌드 메소드에서 화면을 꽉 채우는 Container 안에 GridView 사용해서 코드를 작성하겠습니다.

Container의 child 속성에 GirdView.count 생성자로 GridView 위젯을 반환하고 있습니다. 세로로 스크롤하려는 경우 scrollDirectiond은 Axis.vertival로 설정합니다. crossAxisCount는 세로로 스크롤할 때 각 행에 표시되는 항목 수입니다. children속성에서 createBox 함수를 호출하여 50개의 상자 위젯을 가져옵니다. 

createBox는 색깔을 가지는 Container 위젯의 배열을 리턴해주는 메서드이고 아래와 같은 코드를 가지고 있습니다.

 

앱 화면을 살펴보겠습니다.

세로로 스크롤이 가능한 그리드 레이아웃이 생성되었습니다.

 

사각형 사이에 공간을 두고 싶으면 mainAxisSpacing을 사용하여 기본 축에 간격을 추가할 수 있습니다.

 

crossAxisSpacing에 대해서도 동일한 값 5.0을 설정해 보겠습니다.

 

만약 GridViw 외각에 공간을 두고 싶다면  padding을 사용하시면 됩니다.

GridView의 기본적인 사용법은 여기까지 입니다. 이제 갤러리를 만들 차례입니다.


GridView로 갤러리 만들기

GridView의 가장 좋은 사용 사례 중 하나는 사진 갤러리입니다. createGallery라는 위젯 목록을 반환하는 새 매서드를 만들겠습니다.

createGallery는 몇 개의 위젯을 만들지 numImg로 받아서 이미지를 가지는 컨테이너를 리스트로 돌려주는 매소드입니다. 매소드를 살펴보면, urls 변수에 이미지의 패스를 가지는 문자열 배열을 담아두었습니다. 그리고 numImg의 개수만큼 루프를 돌며 컨테이너를 만들고 배열에 담은 후 배열을 리턴하게 됩니다.

이제 GridView에서 createGallery를 호출하도록 수정하겠습니다.

crossAxisCount를 2로 수정하였고, children에서 createGallery를 호출하고 있습니다.

앱 화면을 살펴보겠습니다.

GirdView 로 사진 로드

그리드로 사진들이 잘 표시되고 있습니다. 하지만 이미지의 크기가 맞지 않아 먼가 어색해 보입니다. 그리드의 모든 이미지가 동일한 크기로 출력되도록 수정해 보겠습니다.

 

BoxDecoration으로 그리드의 이미지 크기 조절하기

Grid의 모든 이미지를 같은 크기로 하는 여러 가지 방법이 있지만 Container와 BoxDecoration을 사용하면 매우 쉽게 목적을 달성할 수 있습니다.

Container의 decoration에 BoxDecoration을 설정하였습니다. BoxDecoration의 image에는 DecorationImage를 사용하였고 fit 속성에 BoxFit.cover를 설정함으로 그리드에 표시되는 이미지의 크기를 동일하게 해주고 있습니다.

화면을 보겠습니다.

이제 갤러리의 사진들이 동일한 크기를 가지게 되었습니다.

 

*예제에서 사용한 코드

import 'package:flutter/material.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        title: 'GridView',
        home: Scaffold(
            appBar: 
              AppBar(title: const Text('GridView')
            ), 
            backgroundColor: Colors.indigo.shade100,
            body: const Home()
        )
    );
  }
}

class Home extends StatelessWidget {
  const Home({ Key? key }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    final sizeX = MediaQuery.of(context).size.width;
    final sizeY = MediaQuery.of(context).size.height;
    return Container(
      width: sizeX,
      height: sizeY,
      child: GridView.count(
        scrollDirection: Axis.vertical,
        crossAxisCount: 2,
        children: createGallery(50),
        mainAxisSpacing: 5.0,
        crossAxisSpacing: 5.0,
        padding: const EdgeInsets.all(5.0),
      )
    );
  }

  List<Widget> createGallery(int numImg) {
    List<Widget> images = [];
    List<String> urls = [];
    urls.add('assets/burger1.jpg');
    urls.add('assets/burger2.jpg');
    urls.add('assets/burger3.jpg');
    urls.add('assets/burger4.jpg');
    urls.add('assets/burger5.jpg');

    Widget image;
    int i = 0;
    while (i<numImg) {
      image = Container(
        decoration: BoxDecoration(
          image: DecorationImage(
            fit: BoxFit.cover,
            image: AssetImage(urls[i%5]))
        ),
      );
      images.add(image);
      i++;
    }
    return images;
  }
  
}

 


여기까지 수고하셨습니다.

댓글