Slider & DatePicker
Input rentang angka dan tanggal dengan dialog bawaan.
Kenapa Slider & DatePicker Ada?
Mengetik angka di keyboard HP itu lambat dan rawan salah, apalagi untuk nilai dalam rentang seperti "budget maksimal" atau "jarak pencarian". Slider menyelesaikan masalah ini dengan kontrol visual langsung: user menggeser, angka mengikuti, dan batas min/max mustahil dilanggar.
Tanggal lebih parah lagi: format beda-beda (dd/mm/yyyy vs mm/dd/yyyy), validasi tanggal kabisat, dan memastikan tanggal tidak di masa lalu untuk tanggal lahir. showDatePicker bawaan Flutter menyelesaikan semuanya sekaligus, lengkap dengan kalender yang sudah dioptimasi untuk sentuhan.
Slider Dasar
double _harga = 50000;
Slider(
value: _harga,
min: 10000,
max: 200000,
divisions: 19,
label: 'Rp${_harga.toInt()}',
onChanged: (v) => setState(() => _harga = v),
)divisions memecah rentang menjadi langkah-langkah diskrit sehingga slider "melompat" per langkah dan menampilkan label angka saat digeser. Tanpa divisions, slider bergerak mulus dan label tidak muncul. Nilai value wajib bertipe double dan harus selalu berada di antara min dan max, kalau tidak Flutter melempar assertion error saat debug.
Contoh Nyata: Filter Harga
Di halaman katalog, slider biasanya dipasangkan dengan teks ringkasan dan dipisahkan dari pemanggilan API:
double _maks = 100000;
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text('Harga maksimal',
style: TextStyle(fontWeight: FontWeight.bold)),
Slider(
value: _maks,
min: 0,
max: 500000,
divisions: 50,
label: 'Rp${_maks.toInt()}',
onChanged: (v) => setState(() => _maks = v),
onChangeEnd: (v) => _cariProduk(v), // panggil API sekali saja
),
Text('Menampilkan produk di bawah Rp${_maks.toInt()}'),
],
)Perhatikan onChangeEnd: ia dipanggil sekali saat user melepas slider, sedangkan onChanged dipanggil puluhan kali selama drag. Jangan pernah memanggil API atau query database di dalam onChanged, pindahkan ke onChangeEnd.
DatePicker: Pola Async
showDatePicker mengembalikan Future, jadi pemanggilnya harus async dan hasilnya bisa null (user menekan batal):
DateTime? _tanggal;
ElevatedButton(
onPressed: () async {
final hasil = await showDatePicker(
context: context,
initialDate: _tanggal ?? DateTime.now(),
firstDate: DateTime(2000),
lastDate: DateTime(2100),
);
if (hasil != null && mounted) {
setState(() => _tanggal = hasil);
}
},
child: Text(_tanggal == null
? 'Pilih Tanggal'
: '${_tanggal!.day}/${_tanggal!.month}/${_tanggal!.year}'),
)Untuk format tanggal yang rapi sesuai locale, pakai package intl: DateFormat('d MMM yyyy', 'id').format(_tanggal!) menghasilkan "8 Okt 2026". Jangan format manual dengan string interpolation untuk aplikasi multi-bahasa, karena urutan hari/bulan/tahun beda tiap locale.
Edge Case & Best Practice
Pertama, initialDate harus berada di antara firstDate dan lastDate, kalau tidak dialog error sebelum tampil. Kedua, setelah await, selalu cek mounted sebelum setState atau memakai context lagi, karena user bisa pindah halaman saat dialog terbuka. Ketiga, untuk input tanggal lahir yang jauh di masa lalu, date picker bawaan melelahkan karena harus scroll tahun puluhan kali, pertimbangkan membatasi firstDate atau memakai dropdown tahun.
Keempat, Slider tanpa label angka membingungkan, user tidak tahu nilai pastinya, jadi selalu tampilkan nilai di label atau teks pendamping. Kelima, ingat aksesibilitas: Slider bisa dioperasikan keyboard di desktop dan dibaca screen reader, tapi pastikan ada Text yang mengumumkan nilai saat ini.
Kapan TIDAK Memakai Ini
Untuk nilai yang butuh presisi penuh seperti nominal transfer, pakai TextField dengan input formatter, slider tidak cocok. Untuk memilih satu dari sedikit opsi diskrit (mis. 1, 2, atau 3 orang), SegmentedButton lebih jelas daripada slider. Dan untuk tanggal yang butuh jam juga, gabungkan showDatePicker dengan showTimePicker, jangan memaksa user mengetik "08/10/2026 14:30" secara manual.
Catatan teknis: Ada juga
RangeSlideruntuk memilih rentang min-max sekaligus (mis. filter harga Rp50rb sampai Rp200rb). Ia memakaiRangeValuesdanonChangedyang mengembalikanRangeValues, pola state-nya mirip Slider biasa.
Tantangan
Filter harga
Buat Slider 0-100000 dengan divisions 20. Di bawahnya tampilkan teks 'Maks: Rp[nilai]'. Nilai default 50000.