flutterlistviewscrollPemula3 mnt baca

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

dart
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:

dart
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:

dart
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 ListView di dalam Column tanpa pembungkus, karena Column memberi tinggi tak terbatas dan ListView butuh tinggi pasti. Hasilnya error viewport. Solusinya: bungkus ListView dengan Expanded, atau set shrinkWrap: true (ListView hanya sebesar isinya, tapi kehilangan lazy rendering penuh jadi kurang efisien untuk list panjang), atau pakai SingleChildScrollView + Column untuk konten pendek yang campuran.