Hầu hết ứng dụng đều cần nhập liệu: đăng nhập, đăng ký, tìm kiếm. Bài này dạy TextField, TextEditingController, Form với kiểm tra hợp lệ và các điều khiển chọn.
- Dùng TextField và TextEditingController
- Xây dựng Form với validator
- Dùng Checkbox, Switch, Radio, Dropdown, DatePicker
- Quản lý bàn phím và focus
- Controller
- Đối tượng đọc/ghi giá trị ô nhập.
- Validator
- Hàm trả về chuỗi lỗi hoặc null nếu hợp lệ.
- GlobalKey<FormState>
- Khóa để truy cập và kiểm tra toàn bộ Form.
- FocusNode
- Quản lý ô đang được nhập.
Khái niệm và lý thuyết
Mỗi ô nhập giữ giá trị trong một TextEditingController. Controller là tài nguyên nên phải tạo trong initState (hoặc khai báo trường) và giải phóng trong dispose.
Form gom nhiều TextFormField; khi gọi formKey.currentState!.validate(), Flutter chạy validator của từng ô và hiện thông báo lỗi ngay dưới ô sai. Kiểm tra phía ứng dụng chỉ để trải nghiệm tốt hơn; máy chủ vẫn phải kiểm tra lại.
Form đăng nhập
class DangNhap extends StatefulWidget {
const DangNhap({super.key});
@override
State<DangNhap> createState() => _DangNhapState();
}
class _DangNhapState extends State<DangNhap> {
final _formKey = GlobalKey<FormState>();
final _email = TextEditingController();
final _matKhau = TextEditingController();
bool _an = true;
@override
void dispose() { _email.dispose(); _matKhau.dispose(); super.dispose(); }
@override
Widget build(BuildContext context) => Form(
key: _formKey,
child: Column(children: [
TextFormField(
controller: _email,
keyboardType: TextInputType.emailAddress,
decoration: const InputDecoration(labelText: 'Email', prefixIcon: Icon(Icons.email)),
validator: (v) => (v == null || !v.contains('@')) ? 'Email không hợp lệ' : null,
),
TextFormField(
controller: _matKhau,
obscureText: _an,
decoration: InputDecoration(labelText: 'Mật khẩu',
suffixIcon: IconButton(icon: Icon(_an ? Icons.visibility : Icons.visibility_off),
onPressed: () => setState(() => _an = !_an))),
validator: (v) => (v ?? '').length < 8 ? 'Tối thiểu 8 ký tự' : null,
),
const SizedBox(height: 16),
FilledButton(
onPressed: () {
if (_formKey.currentState!.validate()) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Xin chào ${_email.text}')));
}
},
child: const Text('Đăng nhập')),
]),
);
}Các điều khiển chọn
| Widget | Dùng cho |
|---|---|
| Checkbox / CheckboxListTile | Đồng ý điều khoản, chọn nhiều |
| Switch / SwitchListTile | Bật tắt |
| RadioGroup + RadioListTile | Chọn một trong nhiều |
| DropdownMenu | Danh sách thả xuống |
| showDatePicker | Chọn ngày |
| Slider | Chọn giá trị trong khoảng |
final ngay = await showDatePicker(
context: context, firstDate: DateTime(1950), lastDate: DateTime.now());Đặt textInputAction: TextInputAction.next để nút Enter trên bàn phím chuyển sang ô kế tiếp, và autofillHints để hệ điều hành gợi ý email, mật khẩu đã lưu.
Bàn phím ảo che ô nhập khi màn hình dài: bọc nội dung trong SingleChildScrollView hoặc ListView.
- Hoàn thiện form đăng nhập ở trên, thêm ô “Ghi nhớ” bằng CheckboxListTile.
- Tạo form đăng ký: họ tên, email, ngày sinh (DatePicker), giới tính (Radio), ngành học (Dropdown).
- Kiểm tra mật khẩu nhập lại phải trùng.
- Hiển thị dữ liệu đã nhập trong AlertDialog khi bấm Gửi.
- TextEditingController đọc/ghi ô nhập và phải dispose.
- Form + validator kiểm tra dữ liệu tập trung.
- Flutter có sẵn đủ điều khiển chọn và hộp thoại ngày.
- Chú ý bàn phím, focus và autofill để tăng trải nghiệm.