flutterdialogsnackbarMenengah3 mnt baca

Dialog, AlertDialog, dan SnackBar

Tampilkan konfirmasi, info singkat, dan bottom sheet dengan dialog yang tidak mengganggu alur user.

AlertDialog: minta keputusan user

Dialog dipakai untuk konfirmasi penting atau info yang butuh perhatian. showDialog mengembalikan Future berisi nilai yang di-pop dari dialog.

dart
Future<void> _konfirmasiHapus(BuildContext context, String nama) async {
  final yakin = await showDialog<bool>(
    context: context,
    builder: (context) => AlertDialog(
      title: const Text('Hapus produk?'),
      content: Text('$nama akan dihapus permanen.'),
      actions: [
        TextButton(
          onPressed: () => Navigator.pop(context, false),
          child: const Text('Batal'),
        ),
        TextButton(
          onPressed: () => Navigator.pop(context, true),
          child: const Text('Hapus', style: TextStyle(color: Colors.red)),
        ),
      ],
    ),
  );

  if (yakin == true) {
    debugPrint('Produk dihapus');
  }
}

Hasilnya bool?: true kalau user tekan Hapus, false kalau Batal, null kalau dialog ditutup lewat back button atau tap di luar.

SnackBar: info ringan yang hilang sendiri

Untuk pesan seperti "Produk tersimpan" yang tidak butuh respons, pakai SnackBar. Ia muncul di bawah layar lalu hilang otomatis.

dart
ScaffoldMessenger.of(context).showSnackBar(
  const SnackBar(
    content: Text('Produk berhasil disimpan'),
    behavior: SnackBarBehavior.floating,
    duration: Duration(seconds: 2),
  ),
)

SnackBar dengan aksi, misalnya tombol Urungkan setelah hapus, adalah pola UX yang bagus:

dart
ScaffoldMessenger.of(context).showSnackBar(
  SnackBar(
    content: const Text('Produk dihapus'),
    action: SnackBarAction(
      label: 'Urungkan',
      onPressed: () => debugPrint('Hapus dibatalkan'),
    ),
  ),
)

showModalBottomSheet

Untuk pilihan atau form pendek, bottom sheet terasa lebih modern daripada dialog di HP:

dart
showModalBottomSheet(
  context: context,
  builder: (context) => SafeArea(
    child: Column(
      mainAxisSize: MainAxisSize.min,
      children: [
        ListTile(
          leading: const Icon(Icons.photo),
          title: const Text('Dari galeri'),
          onTap: () => Navigator.pop(context),
        ),
        ListTile(
          leading: const Icon(Icons.camera_alt),
          title: const Text('Dari kamera'),
          onTap: () => Navigator.pop(context),
        ),
      ],
    ),
  ),
)

Catatan teknis: Pakai ScaffoldMessenger, bukan Scaffold.of(context).showSnackBar yang sudah deprecated. Dan ingat aturan context across async gap: kalau ada await sebelum showDialog atau showSnackBar, cek context.mounted dulu. Dialog yang dipanggil dengan context halaman yang sudah di-pop akan error atau tampil di tempat yang salah.