ListView.separated

pharmDev·2024년 12월 15일

ListView.separated란?

Flutter에서 ListView.separated는 리스트 아이템 사이에 구분선이나 공백을 추가하고 싶을 때 사용하는 매우 유용한 위젯입니다.
ListView.builder와 유사하게 동적으로 리스트를 생성하지만, 각 아이템 사이에 separatorBuilder로 정의한 위젯을 삽입할 수 있다는 점이 차별화됩니다.


ListView.separated 기본 구조

ListView.separated(
  itemCount: <아이템의 개수>, // 리스트에 표시할 아이템의 총 개수
  itemBuilder: (BuildContext context, int index) {
    return <리스트 아이템 위젯>; // 리스트의 각 항목 UI를 정의
  },
  separatorBuilder: (BuildContext context, int index) {
    return <구분선 위젯>; // 각 항목 사이에 들어갈 위젯 정의
  },
);

주요 속성

  1. itemCount:

    • 리스트에 표시할 아이템의 총 개수.
    • 아이템 개수에 따라 itemBuilderseparatorBuilder가 호출됩니다.
  2. itemBuilder:

    • 리스트의 각 항목을 렌더링하는 함수.
    • 매개변수:
      • context: 위젯 트리의 컨텍스트.
      • index: 현재 항목의 인덱스.
  3. separatorBuilder:

    • 리스트의 각 항목 사이에 삽입할 위젯을 렌더링하는 함수.
    • 첫 번째와 마지막 항목 사이에만 실행됩니다.
    • 매개변수:
      • context: 위젯 트리의 컨텍스트.
      • index: 현재 항목의 인덱스.

예제 1: 기본적인 사용법

간단한 문자열 리스트에 공백 추가

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  final List<String> items = ['Apple', 'Banana', 'Cherry', 'Date', 'Elderberry'];

  
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text('ListView.separated Example')),
        body: ListView.separated(
          itemCount: items.length,
          itemBuilder: (context, index) {
            return ListTile(
              title: Text(items[index]),
            );
          },
          separatorBuilder: (context, index) {
            return SizedBox(height: 16.0); // 아이템 사이 공백 추가
          },
        ),
      ),
    );
  }
}

결과:

  • 각 리스트 항목 사이에 16.0 크기의 공백이 삽입됩니다.

예제 2: 구분선 추가

아이템 사이에 구분선(선 스타일)을 추가

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  final List<String> items = ['Apple', 'Banana', 'Cherry', 'Date', 'Elderberry'];

  
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text('ListView.separated Example')),
        body: ListView.separated(
          itemCount: items.length,
          itemBuilder: (context, index) {
            return ListTile(
              title: Text(items[index]),
            );
          },
          separatorBuilder: (context, index) {
            return Divider( // 구분선 추가
              thickness: 2,
              color: Colors.grey,
            );
          },
        ),
      ),
    );
  }
}

결과:

  • 각 리스트 항목 사이에 두께 2의 회색 선이 삽입됩니다.

예제 3: 동적 데이터와 스타일링

사용자 정보 리스트와 아이템 간격 추가

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  final List<Map<String, String>> users = [
    {'name': 'Alice', 'email': 'alice@example.com'},
    {'name': 'Bob', 'email': 'bob@example.com'},
    {'name': 'Charlie', 'email': 'charlie@example.com'},
  ];

  
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text('User List')),
        body: ListView.separated(
          itemCount: users.length,
          itemBuilder: (context, index) {
            return ListTile(
              leading: CircleAvatar(
                child: Text(users[index]['name']![0]), // 첫 글자 표시
              ),
              title: Text(users[index]['name']!),
              subtitle: Text(users[index]['email']!),
            );
          },
          separatorBuilder: (context, index) {
            return SizedBox(height: 8.0); // 아이템 간 간격
          },
        ),
      ),
    );
  }
}

결과:

  • 각 사용자 정보는 ListTile로 표시.
  • 사용자 정보 사이에 8.0 크기의 공백이 삽입.

예제 4: 복잡한 UI와 separatorBuilder 활용

일정 리스트와 아이템 사이 배경 스타일 추가

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  final List<Map<String, String>> schedules = [
    {'time': '10:00 AM', 'task': 'Meeting with Bob'},
    {'time': '01:00 PM', 'task': 'Lunch with Alice'},
    {'time': '03:00 PM', 'task': 'Doctor Appointment'},
  ];

  
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text('Schedule List')),
        body: ListView.separated(
          itemCount: schedules.length,
          itemBuilder: (context, index) {
            return ListTile(
              title: Text(
                schedules[index]['task']!,
                style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
              ),
              subtitle: Text(schedules[index]['time']!),
              leading: Icon(Icons.event),
            );
          },
          separatorBuilder: (context, index) {
            return Container(
              height: 10.0,
              color: Colors.grey[200], // 회색 배경
            );
          },
        ),
      ),
    );
  }
}

결과:

  • 일정 항목 사이에 회색 배경을 가진 구분선이 삽입.

ListView.separated를 사용하는 이유

  1. 아이템 간 커스터마이징:

    • 구분선, 공백, 배경 등 아이템 사이에 추가적으로 필요한 UI를 쉽게 삽입 가능.
  2. 성능 최적화:

    • ListView.builder와 동일하게 필요한 위젯만 동적으로 생성.
    • 구분선도 동적으로 렌더링되므로 불필요한 렌더링을 방지.
  3. 가독성:

    • UI의 요소를 시각적으로 구분하여 가독성 향상.

ListView.separated와 ListView.builder 비교

특성ListView.builderListView.separated
기본 기능동적으로 리스트 아이템 생성동적으로 리스트 아이템 생성 + 구분선 추가
구분선/공백 삽입수동으로 추가해야 함separatorBuilder를 통해 간단히 구현 가능
사용 시나리오단순한 리스트 렌더링리스트 항목 사이에 추가 UI가 필요한 경우

마무리

ListView.separated는 리스트의 아이템 사이에 구분선이나 공백 같은 추가적인 UI를 삽입할 때 매우 강력하고 유용한 도구입니다.
위의 예제들을 참고하여 상황에 맞는 리스트를 효율적으로 구현해보세요!

Tip: 만약 구분선이 필요 없고 단순 리스트만 렌더링하려면 ListView.builder를 사용하는 것이 더 간단하고 적합합니다. 😊

profile
코딩을 배우는 초보

0개의 댓글