👉 쉽게 말하면
Column + 스크롤 기능 추가된 것
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
Widget build(BuildContext context) {
return const MaterialApp(
home: ListViewBasicExample(),
);
}
}
class ListViewBasicExample extends StatelessWidget {
const ListViewBasicExample({super.key});
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text("ListView 기본")),
body: ListView(
children: const [
ListTile(title: Text("아이템 1")),
ListTile(title: Text("아이템 2")),
ListTile(title: Text("아이템 3")),
ListTile(title: Text("아이템 4")),
],
),
);
}
}
👉 위에서 아래로 스크롤 가능
👉 데이터 많을 때 필수
class ListViewBuilderExample extends StatelessWidget {
const ListViewBuilderExample({super.key});
Widget build(BuildContext context) {
final items = List.generate(20, (index) => "아이템 ${index + 1}");
return Scaffold(
appBar: AppBar(title: const Text("ListView.builder")),
body: ListView.builder(
itemCount: items.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(items[index]),
);
},
),
);
}
}
👉 아이템 사이 구분선 추가
ListView.separated(
itemCount: 10,
itemBuilder: (context, index) {
return ListTile(title: Text("아이템 $index"));
},
separatorBuilder: (context, index) {
return const Divider();
},
)
| ListView | builder |
|---|---|
| 전부 생성 | 필요한 것만 생성 |
| 작은 리스트 | 큰 리스트 |
| 비효율 가능 | 매우 효율적 |
SizedBox(
height: 100,
child: ListView(
scrollDirection: Axis.horizontal,
children: [
Container(width: 100, color: Colors.red),
Container(width: 100, color: Colors.green),
Container(width: 100, color: Colors.blue),
],
),
)
👉 좌우 스크롤
class ProductListExample extends StatelessWidget {
const ProductListExample({super.key});
Widget build(BuildContext context) {
final products = List.generate(10, (i) => "상품 ${i + 1}");
return Scaffold(
appBar: AppBar(title: const Text("상품 리스트")),
body: ListView.builder(
itemCount: products.length,
itemBuilder: (context, index) {
return ListTile(
leading: Container(
width: 50,
height: 50,
color: Colors.grey,
),
title: Text(products[index]),
subtitle: const Text("가격: 10,000원"),
trailing: const Icon(Icons.arrow_forward),
);
},
),
);
}
}
| 타입 | 설명 |
|---|---|
| ListView | 정적 리스트 |
| ListView.builder | 동적 리스트 (추천) |
| ListView.separated | 구분선 포함 |
Column(
children: [
ListView(...) // ❌ 에러 발생
],
)
👉 해결 👇
Expanded(
child: ListView(...),
)
👉 ListView는 스크롤 가능한 Column이다
builderhttps://velog.io/@qazws78941/Flutter-GridView
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
Widget build(BuildContext context) {
return const MaterialApp(home: ProductListExample());
}
}
class ProductListExample extends StatelessWidget {
const ProductListExample({super.key});
Widget build(BuildContext context) {
final products = List.generate(10, (i) => "상품 ${i + 1}");
return Scaffold(
appBar: AppBar(title: const Text("상품 리스트")),
body: ListView.builder(
itemCount: products.length,
itemBuilder: (context, index) {
// return ListTile(
// leading: Container(
// width: 50,
// height: 50,
// color: Colors.grey,
// ),
// title: Text(products[index]),
// subtitle: const Text("가격: 10,000원"),
// trailing: const Icon(Icons.arrow_forward),
// );
return Container(
height: 50,
color: Colors.amber,
child: Center(child: Text('Entry ${products[index]}')),
);
},
),
);
}
}
class ListViewBasicExample extends StatelessWidget {
const ListViewBasicExample({super.key});
Widget build(BuildContext context) {
final items = List.generate(100, (index) => "아이템 ${index + 1}");
return Scaffold(
appBar: AppBar(title: const Text("ListView 기본")),
body: ListView.separated(
itemCount: 10,
itemBuilder: (context, index) {
return ListTile(title: Text("아이템 $index"));
},
separatorBuilder: (context, index) {
return const Divider(
color: Colors.red,
thickness: 2,
height: 30,
indent: 20,
endIndent: 20,
);
},
),
);
}
}
// class ListViewBasicExample extends StatelessWidget {
// const ListViewBasicExample({super.key});
//
// @override
// Widget build(BuildContext context) {
// return Scaffold(
// appBar: AppBar(title: const Text("ListView 기본")),
// body: ListView(
// children: [
// ListTile(title: Text("아이템 1")),
// ListTile(title: Text("아이템 2")),
// ListTile(title: Text("아이템 3")),
// ListTile(title: Text("아이템 4")),
// Text("아이템 4"),
// ],
// ),
// );
// }
// }
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
// MaterialApp 은 StatelessWidget
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'ListView Example',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const HomePage(),
);
}
}
// Scaffold 화면은 StatefulWidget
class HomePage extends StatefulWidget {
const HomePage({super.key});
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
late List<String> items;
@override
void initState() {
super.initState();
items = List.generate(10,(index) => "아이템 $index",);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("ListView.separated"),
),
body: ListView.separated(
itemCount: items.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(items[index]),
onTap: () {
setState(() {
items[index] =
"${items[index]} 클릭됨";
});
},
);
},
separatorBuilder: (context, index) {
return const Divider(
thickness: 1,
);
},
),
);
}
}