Irbisa · Cheatsheet
Forms, Input & Focus
TextField, TextEditingController, Form validation, FocusNode, input formatters, keyboard insets
What is a
TextEditingController, and why must it be created inStaterather than inbuild?class NameField extends StatefulWidget { const NameField({super.key}); @override State<NameField> createState() => _NameFieldState();}…What is the difference between
TextFieldandTextFormField?How do you validate a form in Flutter: what do
Form,GlobalKey<FormState>andvalidatoreach do?class _LoginFormState extends State<LoginForm> { final _formKey = GlobalKey<FormState>(); String _email = ''; void _submit() { final form = _formKey.currentState!;…What is the difference between
onChanged,onSubmittedand aTextEditingControllerlistener?class _SearchState extends State<Search> { final _query = TextEditingController(); String _last = ''; @override void initState() {…What do
labelText,hintText,helperTextanderrorTextdo in anInputDecoration, and why does the form jump when an error appears?What do
keyboardType,textInputActionandtextCapitalizationcontrol on aTextField?What does
Scaffold.resizeToAvoidBottomInsetdo, and why can the keyboard still cover your form's button?Scaffold( // resizeToAvoidBottomInset: true is the default; leave it on body: SafeArea( child: SingleChildScrollView( padding: const EdgeInsets.all(16), child: Column(…After
validate()passes you callsave(), and the model is still empty. Where does aFormactually keep its values?class _CheckoutState extends State<Checkout> { final _formKey = GlobalKey<FormState>(); var _order = const Order(); void _submit() { final form = _formKey.currentState!;…Find the bug: the edit-profile form shows an empty Name field even after the profile has loaded.
class _ProfileFormState extends State<ProfileForm> { Profile? _profile; @override void initState() { super.initState(); widget.repo.load().then((p) { if (mounted) setState(() => _profile = p); }); } @override Widget build(BuildContext context) => TextFormField( initialValue: _profile?.name, decoration: const InputDecoration(labelText: 'Name'), );}A sign-up form opens already covered in red errors. Which
autovalidateModecauses that, and which would you use instead?You show the server's "email already registered" error like this, and it stays after the user fixes the email. Why, and what is the fix?
String? _serverError; // set when the API rejects the email TextFormField( controller: _email, autovalidateMode: AutovalidateMode.onUserInteraction, decoration: InputDecoration( labelText: 'Email', errorText: _serverError, ), validator: (v) => (v ?? '').contains('@') ? null : 'Enter a valid email',)What is a
FocusNode, and how do you move focus to the next field and dismiss the keyboard?class _LoginState extends State<Login> { final _password = FocusNode(); void _hideKeyboard(PointerDownEvent _) => FocusManager.instance.primaryFocus?.unfocus();…The keyboard shows a Next key, but pressing it leaves the cursor in the email field. What is wrong with this code?
Column( children: [ TextField( controller: _email, textInputAction: TextInputAction.next, onEditingComplete: _saveDraft, ), TextField(controller: _password, obscureText: true), ],)How do you build an input mask with a
TextInputFormatter, and why does the caret jump to the end after every keystroke?class ThousandsFormatter extends TextInputFormatter { @override TextEditingValue formatEditUpdate(TextEditingValue old, TextEditingValue next) { final digits = next.text.replaceAll(RegExp(r'\D'), ''); if (digits.isEmpty) return const TextEditingValue();…A
validatormust be synchronous, so how do you show a server-side check like "username is taken" while the user types?class _UsernameFieldState extends State<UsernameField> { Timer? _debounce; int _request = 0; String? _taken; // what the synchronous validator hands back void _onChanged(String value) { _taken = null; // the old verdict was about the old text…Your date picker sits inside a
Form, butvalidate()ignores it andsave()never sees its value. How do you make a non-text widget a real form field?class DateFormField extends FormField<DateTime> { DateFormField({ super.key, super.initialValue, super.validator, super.onSaved,…The OS password manager never offers to fill or save your login form, and the SMS code is typed by hand. What does autofill need in Flutter?
AutofillGroup( // these fields are ONE credential child: Column( children: [ TextField( controller: _email, autofillHints: const [AutofillHints.username], // not .email…With a Bloc driving a search field, characters get lost when typing fast and the caret jumps to the end. Who should own the text?
class _SearchFieldState extends State<SearchField> { final _ctrl = TextEditingController(); @override void dispose() { _ctrl.dispose();…Text typed into a form disappears after rotating the phone. What was destroyed, and when do you actually need
RestorableTextEditingController?class _SignupPageState extends State<SignupPage> with RestorationMixin { // survives process death; a plain controller survives only rebuilds final _email = RestorableTextEditingController(); @override String? get restorationId => 'signup'; // null opts this subtree out…A 30-field form built with
ListView.builderloses typed values and error messages once a field scrolls off screen. What causes it and what do you change?class _LongFormState extends State<LongForm> { final _formKey = GlobalKey<FormState>(); // the page owns the values; a row is just a view of one late final Map<String, TextEditingController> _ctrls = { for (final f in widget.fields) f.id: TextEditingController(text: f.initial), };…This upper-casing formatter scrambles words typed with predictive keyboards and Japanese IMEs. What is
TextEditingValue.composing, and what is wrong here?class ShoutFormatter extends TextInputFormatter { @override TextEditingValue formatEditUpdate(TextEditingValue old, TextEditingValue next) { return TextEditingValue( text: next.text.toUpperCase(), selection: next.selection, composing: next.composing, ); }}