[Flutter] 09. 리스트와 스크롤 - ListView, GridView
스크롤 가능한 리스트와 그리드를 만드는 방법을 배웁니다.
ListView
기본 ListView
적은 수의 아이템에 적합합니다.
ListView(
children: const [
ListTile(
leading: Icon(Icons.email),
title: Text('이메일'),
subtitle: Text('user@example.com'),
trailing: Icon(Icons.arrow_forward_ios),
),
ListTile(
leading: Icon(Icons.phone),
title: Text('전화번호'),
subtitle: Text('010-1234-5678'),
),
ListTile(
leading: Icon(Icons.location_on),
title: Text('주소'),
subtitle: Text('서울시 강남구'),
),
],
)
ListView.builder (대량 데이터)
필요한 아이템만 생성하여 메모리 효율적입니다.
class TodoListPage extends StatelessWidget {
final List<String> items = List.generate(100, (i) => '할일 ${i + 1}');
TodoListPage({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('할일 목록')),
body: ListView.builder(
itemCount: items.length,
itemBuilder: (context, index) {
return ListTile(
leading: CircleAvatar(child: Text('${index + 1}')),
title: Text(items[index]),
onTap: () {
print('${items[index]} 선택');
},
);
},
),
);
}
}
ListView.separated (구분선 포함)
ListView.separated(
itemCount: 20,
separatorBuilder: (context, index) => const Divider(), // 구분선
itemBuilder: (context, index) {
return ListTile(
title: Text('아이템 $index'),
);
},
)
GridView
GridView.count (고정 열 수)
GridView.count(
crossAxisCount: 2, // 2열
crossAxisSpacing: 10, // 가로 간격
mainAxisSpacing: 10, // 세로 간격
padding: const EdgeInsets.all(10),
children: List.generate(6, (index) {
return Container(
decoration: BoxDecoration(
color: Colors.blue[100 * (index % 9 + 1)],
borderRadius: BorderRadius.circular(8),
),
child: Center(
child: Text('아이템 $index', style: const TextStyle(fontSize: 16)),
),
);
}),
)
GridView.builder (대량 데이터)
GridView.builder(
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3, // 3열
crossAxisSpacing: 8,
mainAxisSpacing: 8,
childAspectRatio: 1.0, // 가로:세로 비율
),
itemCount: 30,
padding: const EdgeInsets.all(8),
itemBuilder: (context, index) {
return Card(
child: Center(child: Text('$index')),
);
},
)
SingleChildScrollView
Column 등 스크롤이 안 되는 위젯을 스크롤 가능하게 만듭니다.
SingleChildScrollView(
padding: const EdgeInsets.all(16),
child: Column(
children: [
Container(height: 200, color: Colors.red),
const SizedBox(height: 16),
Container(height: 200, color: Colors.green),
const SizedBox(height: 16),
Container(height: 200, color: Colors.blue),
const SizedBox(height: 16),
Container(height: 200, color: Colors.orange),
],
),
)
실습 예제: 연락처 앱
import 'package:flutter/material.dart';
class Contact {
final String name;
final String phone;
final String email;
Contact({required this.name, required this.phone, required this.email});
}
class ContactListPage extends StatelessWidget {
ContactListPage({super.key});
final List<Contact> contacts = [
Contact(name: '홍길동', phone: '010-1111-2222', email: 'hong@test.com'),
Contact(name: '김철수', phone: '010-3333-4444', email: 'kim@test.com'),
Contact(name: '이영희', phone: '010-5555-6666', email: 'lee@test.com'),
Contact(name: '박민수', phone: '010-7777-8888', email: 'park@test.com'),
Contact(name: '정수진', phone: '010-9999-0000', email: 'jung@test.com'),
];
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('연락처')),
body: ListView.builder(
itemCount: contacts.length,
itemBuilder: (context, index) {
final contact = contacts[index];
return Card(
margin: const EdgeInsets.symmetric(horizontal: 12, vertical: 4),
child: ListTile(
leading: CircleAvatar(
backgroundColor: Colors.blue,
child: Text(
contact.name[0],
style: const TextStyle(color: Colors.white),
),
),
title: Text(contact.name),
subtitle: Text(contact.phone),
trailing: IconButton(
icon: const Icon(Icons.call, color: Colors.green),
onPressed: () {
print('${contact.name}에게 전화');
},
),
onTap: () {
print('${contact.name} 상세 보기');
},
),
);
},
),
floatingActionButton: FloatingActionButton(
onPressed: () {
print('연락처 추가');
},
child: const Icon(Icons.add),
),
);
}
}
- [Flutter] 18. 빌드와 배포 - APK, App Store
- [Flutter] 17. 실전 프로젝트 - Todo 앱 만들기
- [Flutter] 16. 패키지 활용 - 유용한 패키지 소개
- [Flutter] 15. 디자인 - 테마, 스타일, 반응형
- [Flutter] 14. 로컬 저장소 - SharedPreferences, SQLite
- [Flutter] 13. HTTP 통신 - REST API 연동
- [Flutter] 12. 상태관리 - setState, Provider
- [Flutter] 11. 사용자 입력 - Form, TextField, 버튼
- [Flutter] 10. 화면 이동 - Navigation, Route
- [Flutter] 09. 리스트와 스크롤 - ListView, GridView
- [Flutter] 08. 레이아웃 - Row, Column, Stack
- [Flutter] 07. 위젯 기초 - StatelessWidget, StatefulWidget
- [Flutter] 06. Flutter 소개 및 개발환경 설치
- [Flutter] 05. Dart 비동기 - Future, async/await, Stream
- [Flutter] 04. Dart 클래스 - OOP 기초
- [Flutter] 03. Dart 함수 - 선언, 매개변수, 람다
- [Flutter] 02. Dart 제어문 - 조건문, 반복문
- [Flutter] 01. Dart 언어 기초 - 변수, 타입, 연산자