TextFormField validator not working - The method 'validate' was called on null

If someone have the same error even adding the key and your structure is:

Form => ListView => [TextFormField(s)], 

try to change the structure:

Form => SingleScrollView => Column

This change worked for me.

Happy coding.


The question was already solved, but if it's still not working after adding the key and changing the structure to one of the following:

Form => SingleChildScrollView => Column => [TextFormField(s)],

or

SingleChildScrollView => Form => Column => [TextFormField(s)],

Try adding:

autovalidateMode: AutovalidateMode.onUserInteraction

For example:

TextFormField(
  decoration: const InputDecoration(
    icon: Icon(Icons.person),
    labelText: 'User:',
  ),
  onSaved: (){},
  autovalidateMode:
      AutovalidateMode.onUserInteraction,
  validator: (value) {
    if (value == null || value.isEmpty) {
      return 'Please enter your user name.';
    } else if (value.contains('@')) {
      return 'Please don\'t use the @ char.';
    }
    return null;
  },
  textInputAction: TextInputAction.next,
),

You didn't add the key to the form, this code should work:

class _LoginForm extends State<LoginForm> {
  // GlobalKey<FormState> formKey = GlobalKey();
  final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
  String _email;
  String _password;

  void validateAndSave() {
    final FormState form = _formKey.currentState;
    if (form.validate()) {
      print('Form is valid');
    } else {
      print('Form is invalid');
    }
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      padding: EdgeInsets.only(left: 15.0, right: 15.0),
      child: Form(
        key: _formKey,
        child: Column(
          // mainAxisAlignment: MainAxisAlignment.center,
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: <Widget>[
            SizedBox(
              height: 150.0,
            ),
            // input field for email
            TextFormField(
              decoration: InputDecoration(labelText: 'Email'),
              validator: (value) =>
                  value.isEmpty ? 'Email cannot be blank' : null,
              // onSaved: (value) => _email = value,
            ),
            // input field for password
            TextFormField(
              decoration: InputDecoration(labelText: 'Password'),
              obscureText: true,
              validator: (value) =>
                  value.isEmpty ? 'Password cannot be blank' : null,
              // onSaved: (value) => _password = value,
            ),
            RaisedButton(
              child: Text(
                'Login',
                style: TextStyle(fontSize: 20.0),
              ),
              onPressed: validateAndSave,
            ),
          ],
        ),
      ),
    );
  }
}