본문 바로가기
CODE/Flutter

[Flutter] ListView & GridView 사용하기

by Nuridal_class 2023. 12. 14.
728x90
728x90

 ListView 사용해 보기

사용해야 하는 데이터가 순차적으로 보여줘야 하는 데이터라면 일일이 하나씩 빼서 쓰기에는 너무 비효율적이다.
그렇게 이번에는 ListView를 사용하는 방법에 대해서 알아보도록 하자.

 

ListView.builder 사용하기

ListView를 그대로 사용해도 되지만 개발하면서 많이 쓰일 것은 ListView.builder이라 생각이 듭니다.
그러해서 ListView.builder를 사용하는 방법에 대해서 간단하게 알아보겠습니다.

 

 파일 구성하기  👉 1. main.dart

먼저 메인페이지에서 ListView를 구성해 놓은 페이지로 이동하는 코드로 시작합니다.
class _ViewsetStateState extends State<ViewsetState> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
            backgroundColor: Theme.of(context).colorScheme.inversePrimary,
            title: const Text('Nuridal Class: Views',
                style: TextStyle(fontSize: 20))),
        body: Center(
            child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[
              ElevatedButton(
                onPressed: () {
                //📲 main페이지에서 list_view페이지로 이동하는 코드
                  Navigator.pushNamed(context, '/list_view');
                },
                child: const Text('listview_page'),
              )
            ])));
  }
}

 

 2. Future loadAssetsImgaes()

이미지를 ListView에 담으려고 하는데 이미지가 여러 장인데 일일이 타이핑하기에는 너무 많은 양이 될 것이다
그래서 assets 폴더 안에 이미지를 넣어두고 가져오는 함수가 필요한데 아래와 같다
Future<List<String>> loadAssetsImages({
  required String path,
  required String extension,
}) async {
  final manifestContent = await rootBundle.loadString('AssetManifest.json');
  final Map<String, dynamic> manifestMap =
      Map<String, dynamic>.from(json.decode(manifestContent));

  List<String> imagePaths = manifestMap.keys.where((String key) {
  //📲 path로 폴더의 경로를 기입한다
  //📲 extension으로 확장자 명을 기입한다
    return key.startsWith(path) && key.toLowerCase().endsWith(extension);
  }).toList();

  return imagePaths;
}

 

 3. list_view.dart

이제는 함수를 사용해서 이미지를 가져오면 되는데 FutureBuilder를 사용해도 되지만 이번엔 그냥 불러오겠습니다.
  //📲 이미지를 넣기위한 리스트 생성
  List<String> imageList = [];

  @override
  void initState() {
    //📲 화면이 처음 생성될때 loadImage() 함수를 통해 이미지를 가져온다
    loadImage();
    super.initState();
  }

  void loadImage() async {
    //📲 image list안에 위에서 생성한 loadAssetsImages 함수를 가져와서 할당하는 부분
    List<String> images =
        await loadAssetsImages(path: 'assets/', extension: '.png');
    //📲 새로고침을 통해서 전역변수였던 imageList 안에 images를 할당해줍니다
    setState(() {
      imageList = images;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
            backgroundColor: Theme.of(context).colorScheme.inversePrimary,
            title: const Text('Nuridal Class: Listview',
                style: TextStyle(fontSize: 20))),
        body: Center(
            child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[
              SizedBox(
              //📲 ListView.builder을 선언하기 전에 먼저 높이를 설정해줘서 오류를 피해줍니다.
              //📲 자세한 설명은 포스팅이 되어 있으니 확인!
                height: 300,
                child: ListView.builder(
                  padding: const EdgeInsets.all(8),
                  //📲 몇번을 수행할것인가에 대해서 미리 생성해둔 imageList의 길이를 가져오는 부분
                  itemCount: imageList.length,
                  itemBuilder: (BuildContext context, int index) {
                    return Center(
                    //📲 index로 imageList 안에 있는 이미지들을 모두 가져옵니다
                    //📲 Image.asset 다른 옵션들로 크기 등 조정할 수 있습니다
                      child: Image.asset(imageList[index]),
                    );
                  },
                ),
              ),
              ElevatedButton(
                onPressed: () {
                  Navigator.pop(context);
                },
                child: const Text('back_page'),
              )
            ])));
  }
}

 

 4. 결괏값 확인하기

버튼 이벤트를 수행하면 할당했던 이미지들이 순차적으로 표시되는 것을 볼 수 있습니다.
이때 나는 세로가 아닌 가로로 보고 싶다 하면 코드 한 줄만 더 추가해 주시면 됩니다
  child: ListView.builder(
  	//📲 Axis.horizontal이라는 옵션을 통해서 이미지를 가로로 표시할 수 있습니다
    scrollDirection: Axis.horizontal,
    padding: const EdgeInsets.all(8),
    itemCount: imageList.length,
    itemBuilder: (BuildContext context, int index) {
      return Center(
        child: Image.asset(imageList[index]));
     }),

flutter ListView imagesflutter ListView images horizontal
[왼 - 세로 이미지 표시 , 오 - 가로 이미지 표시]

 

 

그런데 이 이미지들을 한 화면에 모두 담고 싶을 땐 어떻게 해야 할까?

 

 GridView 사용해 보기

ListView를 어떻게 쓰는지는 대충 알겠는데 개발하면서 난 이미지나 라디오 버튼 등을 한 화면에서 보여줘야 할 때
있다. 물론 ListView를 여러 번 쓰면 되겠지만 그건 너무 비효율적이며 코딩도 복잡해진다
그렇다면 GridView를 사용해서 개발해 보는 건 어떻게? 한번 알아보자

 

파일구성하기 👉 1. grid_view.dart

그전에 똑같이 main.dart에서 route 할당해 주고 버튼을 하나 더 만들어 주면 됩니다.
//📲 이외의 코드는 list_view.dart 코드와 동일합니다
           SizedBox(
                height: 400,
                child: GridView.builder(
                  gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
                    crossAxisCount: 3, //📲1 개의 한 행에 보여줄 개수
                    childAspectRatio: 1 / 1, //📲item 의 가로, 세로 비율
                    mainAxisSpacing: 0, //📲수평 Padding
                    crossAxisSpacing: 0, //📲수직 Padding
                  ),
                  itemCount: imageList.length,
                  itemBuilder: (BuildContext context, int index) {
                    return Center(
                      child: Image.asset(imageList[index]),
                    );
                  },
                ),
              ),

 

2. 결과화면

버튼 이벤트를 수행하면 이미지들이 한 화면에 옵션들을 설정한 대로 나오는 것을 볼 수 있습니다.
이미지만 넣었지만 여기에 라디오 버튼이라던지 onTap 이벤트를 줘서 여러 가지 방향으로 개발을 진행할 수 있습니다.

Flutter GridView

 

오류가 발생하면??

만약 ListView나 GridView에서 오류가 발생한다면?

이 포스팅을 참고하시면 대부분의 오류를 해결하실 수 있으실 겁니다!

 

[Flutter error] RenderBox was not laid out: RenderViewport#d4bc2 NEEDS-LAYOUT NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE'package:

ListView error 제목에서 보이는 오류는 대부분 ListView나 GridView를 사용할때 보이는 오류이다. 또는 아래 사진과 같이 Horizontal viewport was given unbounded height. 이런 오류를 심심치 않게 볼수 있는데 해결

nuridal-class.tistory.com


👉 github에 아주 간단하지만 초기 코드들을 올려두었습니다.
      사용하실 분들은 사용해도 무관합니다.
 

GitHub - Jeoungeunseok/list_grid_view: list_view와 grid_view에 대해서 알아보는 프로젝트

list_view와 grid_view에 대해서 알아보는 프로젝트. Contribute to Jeoungeunseok/list_grid_view development by creating an account on GitHub.

github.com

ListView와 GridView에 대해서 간략하게 알아보았습니다.
개발하실 때에 조금이라도 도움이 되었으면 좋겠습니다.
코딩이 쉬워지는 그날까지!!

728x90
300x250