본문 바로가기
Flutter

[Flutter] List.generate와 ListView.builder의 사용

by haku-s 2024. 6. 25.
728x90

Flutter에서 ListView Widget은 스크롤 가능한 위젯 목록을 표시하는데 사용되며, 정말 많이 사용하는 Widget 중 하나입니다.

ListView에서 항목을 동적으로 생성하기 위해 Flutter에서는 List.generate와 ListView.builder를 제공합니다.

 

List.generate

- 구성

List.generate(
  int length,
  E generator(int index),
  {bool growable = true}
)

* lengh: 생성할 목록의 길이

* generator: index를 가져와서 해당 index의 을 반환하는 함수

* growable: true인 경우 생성된 목록을 늘릴 수 있음. 기본 값은 true

 

- 예제

void main() {
  List<int> numbers = List.generate(10, (index) => index);
  print(numbers); 
}
// Output: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

 

ListView.builder

- 구성

ListView.builder(
  itemCount: int,
  itemBuilder: BuildContext context, int index,
  {Key key, Axis scrollDirection = Axis.vertical, bool reverse = false, ScrollController controller, bool primary, ScrollPhysics physics, bool shrinkWrap = false, EdgeInsetsGeometry padding, double itemExtent, Widget prototypeItem, bool addAutomaticKeepAlives = true, bool addRepaintBoundaries = true, bool addSemanticIndexes = true, double cacheExtent, int semanticChildCount}
)

* itemCount: 목록에 있는 항목 수

* itemBuilder: Context와 index를 가져와 해당 index에 대한 위젯을 반환하는 함수

 

- 예제

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text('ListView.builder Example')),
        body: MyListView(),
      ),
    );
  }
}

class MyListView extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ListView.builder(
      itemCount: 100,
      itemBuilder: (context, index) {
        return ListTile(
          leading: Icon(Icons.person),
          title: Text('Item $index'),
        );
      },
    );
  }
}
// 100개의 항목이 있는 ListView를 생성하고 각 항목에는 아이콘과 해당 index를 표시하는 Text가 포함

 

일반적으로 다른 언어에서 반복된 동작을 할 때에는 for loop를 사용했습니다.

그러나 Flutter에서 ListView 위젯을 사용할 때, 다음과 같은 이유로 for loop의 사용을 지양하는게 좋습니다.

 

※ for를 사용하지 않는 이유

 - for loop를 사용하면 목록을 수동으로 채워야 하기 때문에 오류가 발생하기 쉽다.

 - 코드 가독성 및 유지 관리에서 효율적이지 않다.

 

다음의 예시로 각 코드의 사용법과 가독성을 알아봅시다.

 - for loop

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text('Using for Loop Example')),
        body: MyListView(),
      ),
    );
  }
}

class MyListView extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    List<int> numbers = [];
    for (int i = 0; i < 10; i++) {
      numbers.add(i);
    }

    return ListView(
      children: numbers.map((number) {
        return ListTile(
          leading: Icon(Icons.label),
          title: Text('Item $number'),
        );
      }).toList(),
    );
  }
}

 

 

- List.generate

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text('Using List.generate Example')),
        body: MyListView(),
      ),
    );
  }
}

class MyListView extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    List<int> numbers = List.generate(10, (index) => index);

    return ListView(
      children: numbers.map((number) {
        return ListTile(
          leading: Icon(Icons.label),
          title: Text('Item $number'),
        );
      }).toList(),
    );
  }
}

 

 

- ListView.builder

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text('Using ListView.builder Example')),
        body: MyListView(),
      ),
    );
  }
}

class MyListView extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ListView.builder(
      itemCount: 10,
      itemBuilder: (context, index) {
        return ListTile(
          leading: Icon(Icons.label),
          title: Text('Item $index'),
        );
      },
    );
  }
}
728x90