[Flutter]Listview

한상욱·2023년 3월 1일
0

Flutter 위젯

목록 보기
10/22
post-thumbnail

들어가며

이번 포스팅에서 다룰 주제는 ListView입니다. 영문해석 그대로 List의 내용을 화면으로 띄어주도록하는 위젯인데요. 이 위젯은 UI를 구성하는데 있어서, 데이터를 요청해서 읽어온 후 화면에 List의 내용을 보여주는 것이 아주 용이합니다. 즉, 데이터베이스의 내용을 읽어들여 화면에 그릴 때 굉장히 효율적이에요. 그러면 바로 들어가겠습니다.

환경 구성

ListView를 알아보기위한 페이지 클래스를 하나 만들겠습니다.

import 'package:flutter/material.dart';

class ListViewPage extends StatelessWidget {
  const ListViewPage({super.key});

  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('ListView'),
      ),
    );
  }
}

이제 준비가 끝났습니다 !

ListView

ListView는 List의 내용을 보여준다고 했습니다. 그래서 Column위젯처럼 child가 아니라 children을 자식들로 갖습니다. 기본적으로 ListView는 스크롤기능이 있어서, 화면에 overflow가 나지 않습니다. 3개의 Container위젯을 ListView로 화면에 그려보겠습니다. 그러기 위해서 미리 Container위젯을 준비하겠습니다.

...
      ),
      body: Container(),
    );
  }

  Widget _container1() {
  	height: 100,
    return Container(
      color: Colors.red,
    );
  }

  Widget _container2() {
   	height: 100,
    return Container(
      color: Colors.green,
    );
  }

  Widget _container3() {
    height: 100,
    return Container(
      color: Colors.blue,
    );
  }
}
...

3가지 색상의 Container를 위젯메소드로 만들었습니다. 높이는 100으로 설정했지만, 너비는 설정할 필요가 없습니다. 어짜피 화면 너비를 가득 채워서 ListView의 모습을 볼 수 있습니다. 이제 body에 ListView를 전달하고 childeren에 3개의 위젯메소드를 전달하겠습니다.

  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('ListView'),
      ),
      body: ListView(
        children: [
          _container1(),
          _container2(),
          _container3(),
        ],
      ),
    );
  }

이제 핫리로딩 후 화면을 보게 되면, 3가지 컨테이너가 그려지게된 것을 볼 수 있습니다.

ListView는 이렇게 전달된 위젯들이 아래방향으로 정렬되어 있습니다. 하지만, 굳이 아래방향으로 사용할 필요는 없습니다. ListView에는 scrollDirection인자가 존재하는데, 가로로 스크롤할지, 세로로 스크롤할지 정의할 수 있습니다.

...
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('ListView'),
      ),
      body: ListView(
        scrollDirection: Axis.horizontal,
        children: [
          _container1(),
          _container2(),
          _container3(),
        ],
      ),
...

이제, Container위젯의 높이가 쭈욱 늘어지게 될테니 100으로 정의한 값은 무쓸모입니다. 너비를 정의해서 100을 전달합니다.

신기하죠?? 기본적인 ListView였습니다.

ListView.builder

기존의 ListView.builder는 ListView와 builder를 합친 개념으로 List의 내용을 화면에 그대로 출력시켜줍니다. 헌데, builder를 통해서 출력하기 때문에 자식 위젯들을 일일이 생성해줄 필요 없이 랜더 가능합니다. 일단 예시를 볼까요?

  
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text('ListView'),
        ),
        body: ListView.builder(
            itemCount: 20,
            itemBuilder: (context, index) {
              return Container(
                height: 100,
                color: (index % 2 == 0) ? Colors.red : Colors.green,
              );
            }));
  }
}

이 예시는 20개의 Container위젯을 그린것입니다.
ListView.builder는 itemCount와 itemBuilder를 기본적으로 가져야합니다. itemCount는 itemBuilder를 통해 호출할 위젯의 갯수를 정하고, itemBuilder는 context와 index를 전달받아서, 각각의 index마다 Container를 그리게 됩니다. Container의 색상을 하나로 지정하면 구분이 되지 않을 것 같아서, index가 짝수인 경우 빨간색을, 홀수인 경우 초록색을 전달했습니다.

당연히 List의 첫번째 인덱스는 0입니다. 그래서 0번부터 19번까지 총 20개의 Container를 반환했습니다. 저 위젯들의 인덱스는 index를 통해서 접근할 수 있습니다. Container의 중앙에 index를 출력해볼까요?

...
        appBar: AppBar(
          title: Text('ListView'),
        ),
        body: ListView.builder(
            itemCount: 20,
            itemBuilder: (context, index) {
              return Container(
                height: 100,
                color: (index % 2 == 0) ? Colors.red : Colors.green,
                child: Center(
                    child: Text(
                  '$index',
                  style: TextStyle(fontSize: 30, color: Colors.white),
                )),
              );
            }));
...

이렇게 하면 중앙에 인덱스가 출력될겁니다.

여기까지, ListView와 ListView.builder에 대해 알아봤습니다 ! 자세한 내용은 공식문서를 확인해주세요. 아래는 전체 소스코드입니다.

ListView 공식문서 확인하기

전체 소스코드

import 'package:flutter/material.dart';

class ListViewPage extends StatelessWidget {
  const ListViewPage({super.key});

  
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text('ListView'),
        ),
        body: ListView.builder(
            itemCount: 20,
            itemBuilder: (context, index) {
              return Container(
                height: 100,
                color: (index % 2 == 0) ? Colors.red : Colors.green,
                child: Center(
                    child: Text(
                  '$index',
                  style: TextStyle(fontSize: 30, color: Colors.white),
                )),
              );
            }));
  }
}
profile
개발공부를 기록하자

0개의 댓글