In this guide, we’ll walk through a step-by-step process to implement form validation in Flutter, using a practical example.
You can follow the official documentation to set up Flutter.
Forms are fundamental to many mobile applications, allowing users to input data such as usernames, passwords, and email addresses.
In Flutter, a popular framework for building cross-platform mobile apps, form validation ensures that the data entered by users meets specific criteria before submission.
Table of Contents
Setting Up the Environment:
Before implementing, ensure you have Flutter SDK installed on your system. You can follow the official documentation to set up Flutter: Flutter Installation Guide.

Creating the Flutter Project:
Begin by creating a new Flutter project using the following command:
flutter create form_validation_app
Navigate into the project directory:
cd form_validation_app
Implementing Form Validation in Flutter
Now, let’s implement form validation in Flutter using a sample login form. Open the lib/main.dart file in your preferred code editor and replace its contents with the following code:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: CustomHomePage(),
      theme: ThemeData(
        brightness: Brightness.dark,
      ),
    );
  }
}
class CustomHomePage extends StatefulWidget {
  @override
  _CustomHomePageState createState() => _CustomHomePageState();
}
class _CustomHomePageState extends State<CustomHomePage> {
  var _formKey = GlobalKey<FormState>();
  var isLoading = false;
  void _submit() {
    final isValid = _formKey.currentState!.validate();
    if (!isValid) {
      return;
    }
    _formKey.currentState!.save();
    // Handle form submission
  }
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Custom Form Validation"),
        leading: Icon(Icons.filter_vintage),
      ),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Form(
          key: _formKey,
          child: Column(
            children: <Widget>[
              Text(
                "Custom Form Validation In Flutter",
                style: TextStyle(fontSize: 24.0, fontWeight: FontWeight.bold),
              ),
              SizedBox(
                height: MediaQuery.of(context).size.width * 0.1,
              ),
              TextFormField(
                decoration: InputDecoration(
                  labelText: 'E-Mail',
                  border: OutlineInputBorder(),
                ),
                keyboardType: TextInputType.emailAddress,
                onFieldSubmitted: (value) {
                  //Validator
                },
                validator: (value) {
                  if (value!.isEmpty ||
                      !RegExp(
                              r"^[a-zA-Z0-9.a-zA-Z0-9.!#$%&'*+-/=?^_`{|}~]+@[a-zA-Z0-9]+\.[a-zA-Z]+")
                          .hasMatch(value)) {
                    return 'Enter a valid email!';
                  }
                  return null;
                },
              ),
              SizedBox(
                height: MediaQuery.of(context).size.width * 0.1,
              ),
              TextFormField(
                decoration: InputDecoration(
                  labelText: 'Password',
                  border: OutlineInputBorder(),
                ),
                keyboardType: TextInputType.emailAddress,
                onFieldSubmitted: (value) {},
                obscureText: true,
                validator: (value) {
                  if (value!.isEmpty) {
                    return 'Enter a valid password!';
                  }
                  return null;
                },
              ),
              SizedBox(
                height: MediaQuery.of(context).size.width * 0.1,
              ),
              ElevatedButton(
                style: ElevatedButton.styleFrom(
                  padding: EdgeInsets.symmetric(
                    vertical: 10.0,
                    horizontal: 15.0,
                  ),
                ),
                onPressed: () => _submit(),
                child: Text(
                  "Submit",
                  style: TextStyle(
                    fontSize: 24.0,
                  ),
                ),
              )
            ],
          ),
        ),
      ),
    );
  }
}
About Code
- We start by defining a Flutter app with a dark theme in the 
MyAppclass. - The 
CustomHomePagethe class represents the main page of our app, which extendsStatefulWidget. - Inside 
_CustomHomePageState, we define a form usingFormwidget, and we handle form submissions in_submit()method. - TextFormField widgets are used for email and password inputs with respective validation functions.
 - Upon clicking the submit button, 
_submit()the function is triggered, which validates the form fields. 
if (value!.isEmpty ||
    !RegExp(
        r"^[a-zA-Z0-9.a-zA-Z0-9.!#$%&'*+-/=?^_`{|}~]+@[a-zA-Z0-9]+\.[a-zA-Z]+")
        .hasMatch(value)) {
  return 'Enter a valid email!';
}
This condition is used to validate whether the provided email address (value) is valid or not. Let’s go through each part of the condition:
value!.isEmpty: This part checks if thevalueis empty or not. The!operator negates the result ofisEmpty(), so ifvalueis not empty, this part evaluates tofalse. Ifvalueis empty, it evaluates totrue.RegExp(...): This part creates a regular expression object used for pattern matching. Regular expressions are a powerful tool for pattern matching in strings.- The provided regular expression pattern checks if the email address matches the standard email format. Let’s break down the pattern:
^: Asserts the start of the string.[a-zA-Z0-9.a-zA-Z0-9.!#$%&'*+-/=?^_{|}~]+: Matches one or more characters that can be any alphanumeric character, dot (.), or special characters commonly found in email addresses like!,#,$,%`, etc.@: Matches the “@” symbol.[a-zA-Z0-9]+: Matches one or more alphanumeric characters for the domain name before the dot.\.: Matches the dot (.) character.[a-zA-Z]+: Matches one or more alphabetical characters for the top-level domain (TLD).$: Asserts the end of the string.
 .hasMatch(value): This part checks if the regular expression pattern matches thevalue(the email address). If there’s a match, it returnstrue; otherwise, it returnsfalse.
So, putting it all together:
- If 
valueis empty (value!.isEmptyevaluates totrue), or - If 
valuedoes not match the regular expression pattern for a valid email address (!RegExp(...).hasMatch(value)evaluates totrue), the condition returnstrue, indicating that the email address is not valid. 
In such cases, the function returns the message 'Enter a valid email!', indicating to the user that the provided email address is not in the correct format. Otherwise, if both conditions are false, the function returns null, indicating that the email address is valid.
Output:

Also Read:
Conclusion
Form validation is crucial for ensuring data integrity and enhancing user experience in Flutter applications. By following the steps outlined in this guide, you can easily implement form validation in your Flutter projects. Remember to adapt the validation criteria according to your specific application requirements.