Form dan TextField: Menangkap Input
Bangun input teks yang nyaman dengan TextField, TextEditingController, dan dekorasi yang informatif.
TextField dasar
TextField adalah widget input teks utama. Ia stateful secara internal, jadi kamu tidak perlu setState hanya untuk mengetik.
TextField(
decoration: const InputDecoration(
labelText: 'Nama produk',
hintText: 'cth: Kopi Tubruk',
prefixIcon: Icon(Icons.shopping_bag),
border: OutlineInputBorder(),
),
onChanged: (nilai) => debugPrint('Diketik: $nilai'),
)labelText tampil sebagai label mengambang, hintText sebagai contoh isi, dan prefixIcon memberi ikon di kiri. OutlineInputBorder() memberi bingkai kotak yang rapi.
TextEditingController: membaca dan mengatur teks
Untuk membaca nilai saat tombol ditekan atau mengisi teks secara programatik, pakai controller:
class _FormProdukState extends State<FormProduk> {
final _namaController = TextEditingController();
final _hargaController = TextEditingController();
@override
void dispose() {
_namaController.dispose();
_hargaController.dispose();
super.dispose();
}
void _simpan() {
final nama = _namaController.text.trim();
final harga = int.tryParse(_hargaController.text) ?? 0;
debugPrint('Simpan: $nama seharga $harga');
}
@override
Widget build(BuildContext context) {
return Column(
children: [
TextField(controller: _namaController, decoration: const InputDecoration(labelText: 'Nama')),
const SizedBox(height: 12),
TextField(
controller: _hargaController,
decoration: const InputDecoration(labelText: 'Harga'),
keyboardType: TextInputType.number,
),
const SizedBox(height: 16),
ElevatedButton(onPressed: _simpan, child: const Text('Simpan')),
],
);
}
}Perhatikan int.tryParse(...) ?? 0: jangan pakai int.parse langsung untuk input user karena akan throw kalau user mengetik huruf.
Keyboard yang tepat
Sesuaikan keyboardType dengan data: TextInputType.number untuk angka, TextInputType.emailAddress untuk email, TextInputType.phone untuk nomor HP, TextInputType.multiline untuk alamat. Untuk password tambahkan obscureText: true.
Fokus antar field
Pakai FocusNode dan textInputAction agar tombol enter di keyboard pindah ke field berikutnya:
TextField(
textInputAction: TextInputAction.next,
onSubmitted: (_) => FocusScope.of(context).nextFocus(),
)Detail kecil seperti ini membuat form terasa profesional.
Catatan teknis:
TextEditingControllerwajib di-disposeseperti dibahas di modul lifecycle. Lupa dispose controller di halaman yang sering dibuka-tutup menyebabkan memory leak yang terakumulasi. Juga, jangan membuat controller di dalam methodbuild, karena build bisa dipanggil berkali-kali dan kamu akan membuat controller baru setiap rebuild sambil kehilangan teks yang sudah diketik.