ListView: Daftar yang Bisa Di-scroll
Tampilkan daftar panjang yang mulus dengan ListView.builder, pisahkan item dengan separator yang rapi.
Kenapa tidak pakai Column saja?
Column tidak bisa di-scroll dan me-render semua anaknya sekaligus. Untuk daftar 1000 produk, itu boros memori dan lambat. ListView me-render hanya item yang terlihat di layar (lazy rendering), sehingga daftar sepanjang apa pun tetap mulus.
ListView.builder: pola utama
class DaftarProduk extends StatelessWidget {
const DaftarProduk({super.key});
static const List<String> produk = [
'Kopi Tubruk',
'Es Teh',
'Indomie',
'Roti Bakar',
];
@override
Widget build(BuildContext context) {
return ListView.builder(
itemCount: produk.length,
itemBuilder: (context, index) {
final nama = produk[index];
return ListTile(
leading: const Icon(Icons.fastfood),
title: Text(nama),
trailing: const Icon(Icons.chevron_right),
onTap: () => debugPrint('Klik: $nama'),
);
},
);
}
}itemBuilder dipanggil Flutter hanya untuk index yang sedang terlihat. ListTile adalah widget siap pakai untuk baris daftar dengan leading, title, subtitle, dan trailing.
ListView.separated: dengan pemisah
Untuk garis pemisah antar item, pakai ListView.separated agar tidak perlu menambah Divider manual di setiap item:
ListView.separated(
itemCount: produk.length,
itemBuilder: (context, index) => ListTile(title: Text(produk[index])),
separatorBuilder: (context, index) => const Divider(height: 1),
)ListView horizontal
Ubah arah scroll dengan scrollDirection:
SizedBox(
height: 120,
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: produk.length,
itemBuilder: (context, index) => Container(
width: 100,
margin: const EdgeInsets.only(right: 8),
color: Colors.teal.shade100,
child: Center(child: Text(produk[index])),
),
),
)Perhatikan SizedBox(height: 120) di luarnya. ListView horizontal butuh batas tinggi yang jelas, kalau tidak Flutter tidak tahu seberapa tinggi ia boleh me-render dan akan error.
Catatan teknis: Jangan menaruh
ListViewdi dalamColumntanpa pembungkus, karena Column memberi tinggi tak terbatas dan ListView butuh tinggi pasti. Hasilnya error viewport. Solusinya: bungkus ListView denganExpanded, atau setshrinkWrap: true(ListView hanya sebesar isinya, tapi kehilangan lazy rendering penuh jadi kurang efisien untuk list panjang), atau pakaiSingleChildScrollView+Columnuntuk konten pendek yang campuran.