티스토리 뷰
Flutter는 단일 유형의 아이템뿐만 아니라 다양한 유형의 데이터를 표시할 수 있는 기능을 제공합니다. 리스트에 헤더, 메시지, 섹션 구분선 등을 함께 표시하려면 ListView
와 사용자 정의 클래스를 결합하여 혼합형 리스트를 구현할 수 있습니다. 이번 글에서는 이러한 혼합형 리스트를 구현하는 방법과 주요 포인트를 설명합니다.
참고. Create lists with different types of items
혼합형 리스트란?
혼합형 리스트는 서로 다른 유형의 데이터를 포함하는 리스트를 의미합니다. 예를 들어:
- 헤더: 섹션 구분을 위한 제목.
- 메시지: 사용자 이름과 본문 텍스트.
- 이미지 또는 버튼: 기타 인터랙티브 요소.
이러한 리스트는 단순한 텍스트 나열보다 훨씬 더 풍부한 사용자 경험을 제공합니다.
1단계: 데이터 소스 정의
다양한 유형의 데이터를 다루기 위해 공통 인터페이스 또는 추상 클래스를 정의합니다. 각 데이터 유형은 이 인터페이스를 구현하여 자신만의 렌더링 방식을 제공합니다.
abstract class ListItem {
Widget buildTitle(BuildContext context);
Widget buildSubtitle(BuildContext context);
}
class HeadingItem implements ListItem {
final String heading;
HeadingItem(this.heading);
@override
Widget buildTitle(BuildContext context) {
return Text(
heading,
style: Theme.of(context).textTheme.headlineSmall,
);
}
@override
Widget buildSubtitle(BuildContext context) => const SizedBox.shrink();
}
class MessageItem implements ListItem {
final String sender;
final String body;
MessageItem(this.sender, this.body);
@override
Widget buildTitle(BuildContext context) => Text(sender);
@override
Widget buildSubtitle(BuildContext context) => Text(body);
}
2단계: 데이터 리스트 생성
리스트에 표시할 데이터를 정의합니다. 예를 들어, 헤더와 메시지를 혼합한 데이터를 생성합니다.
final items = List<ListItem>.generate(
100,
(i) => i % 6 == 0
? HeadingItem('Heading $i')
: MessageItem('Sender $i', 'Message body $i'),
);
위 코드는 6번째마다 헤더를 삽입하고 나머지 항목은 메시지로 채웁니다.
3단계: ListView.builder로 데이터 표시
ListView.builder
를 사용하여 데이터를 효율적으로 렌더링합니다. 각 아이템의 유형에 따라 적절한 위젯을 반환합니다.
ListView.builder(
itemCount: items.length,
itemBuilder: (context, index) {
final item = items[index];
return ListTile(
title: item.buildTitle(context),
subtitle: item.buildSubtitle(context),
);
},
);
주요 구현 포인트
1. 타입에 따라 위젯 렌더링
itemBuilder
내부에서 item
의 타입에 따라 HeadingItem
과 MessageItem
을 구분합니다. 이를 통해 각 아이템 유형에 적합한 UI를 구성합니다.
2. 동적 리스트 생성
ListView.builder
는 필요한 아이템만 생성하므로, 대규모 데이터를 다룰 때도 성능이 우수합니다.
3. 스타일링
Theme.of(context).textTheme
을 사용해 헤더와 메시지의 텍스트 스타일을 쉽게 관리할 수 있습니다.
혼합형 리스트의 활용 사례
- 채팅 앱:
- 날짜별 섹션 구분과 메시지 표시.
- 상품 카탈로그:
- 섹션별 카테고리 제목과 상품 리스트.
- 뉴스 피드:
- 기사 헤드라인과 요약 정보.
결론
Flutter에서 혼합형 리스트를 구현하면 다양한 유형의 데이터를 효율적으로 표시할 수 있습니다. ListView.builder
와 사용자 정의 클래스를 활용하여 유연하고 확장 가능한 UI를 만들어 보세요. 이는 채팅 앱, 뉴스 앱, 전자상거래 플랫폼 등 다양한 애플리케이션에서 중요한 역할을 합니다.
import 'package:flutter/material.dart';
void main() {
runApp(
MyApp(
items: List<ListItem>.generate(
1000,
(i) => i % 6 == 0
? HeadingItem('Heading $i')
: MessageItem('Sender $i', 'Message body $i'),
),
),
);
}
class MyApp extends StatelessWidget {
final List<ListItem> items;
const MyApp({super.key, required this.items});
@override
Widget build(BuildContext context) {
const title = 'Mixed List';
return MaterialApp(
title: title,
home: Scaffold(
appBar: AppBar(
title: const Text(title),
),
body: ListView.builder(
// Let the ListView know how many items it needs to build.
itemCount: items.length,
// Provide a builder function. This is where the magic happens.
// Convert each item into a widget based on the type of item it is.
itemBuilder: (context, index) {
final item = items[index];
return ListTile(
title: item.buildTitle(context),
subtitle: item.buildSubtitle(context),
);
},
),
),
);
}
}
/// The base class for the different types of items the list can contain.
abstract class ListItem {
/// The title line to show in a list item.
Widget buildTitle(BuildContext context);
/// The subtitle line, if any, to show in a list item.
Widget buildSubtitle(BuildContext context);
}
/// A ListItem that contains data to display a heading.
class HeadingItem implements ListItem {
final String heading;
HeadingItem(this.heading);
@override
Widget buildTitle(BuildContext context) {
return Text(
heading,
style: Theme.of(context).textTheme.headlineSmall,
);
}
@override
Widget buildSubtitle(BuildContext context) => const SizedBox.shrink();
}
/// A ListItem that contains data to display a message.
class MessageItem implements ListItem {
final String sender;
final String body;
MessageItem(this.sender, this.body);
@override
Widget buildTitle(BuildContext context) => Text(sender);
@override
Widget buildSubtitle(BuildContext context) => Text(body);
}
'Flutter Cookbook' 카테고리의 다른 글
Flutter로 쉽게 리스트뷰 만들기: 초보자를 위한 가이드 (0) | 2024.11.19 |
---|---|
Flutter에서 Floating App Bar 구현하기: SliverAppBar와 CustomScrollView 활용법 (0) | 2024.11.18 |
Flutter에서 가로 스크롤 리스트 구현하기: ListView와 `scrollDirection` 활용법 (0) | 2024.11.16 |
Flutter로 GridView를 활용한 그리드 리스트 구현하기: 가로와 세로 레이아웃의 효율적 구성 (0) | 2024.11.15 |
Flutter로 자연스러운 이미지 페이드인 효과 구현하기: FadeInImage 사용법 (0) | 2024.11.14 |