A Form widget helps group input fields together to manage their validation and saving easily. A GlobalKey lets you access the form's state from anywhere in your code.
Form widget and GlobalKey in Flutter
final _formKey = GlobalKey<FormState>(); Form( key: _formKey, child: Column( children: [ TextFormField( validator: (value) { if (value == null || value.isEmpty) { return 'Please enter some text'; } return null; }, ), ElevatedButton( onPressed: () { if (_formKey.currentState!.validate()) { // Process data } }, child: Text('Submit'), ), ], ), )
The GlobalKey<FormState> uniquely identifies the form and lets you call methods like validate() or save().
The validator function returns a string error message if input is invalid, or null if valid.
final _formKey = GlobalKey<FormState>(); Form( key: _formKey, child: TextFormField( validator: (value) => (value ?? '').isEmpty ? 'Enter text' : null, ), )
ElevatedButton(
onPressed: () {
if (_formKey.currentState!.validate()) {
print('Form is valid');
} else {
print('Form is invalid');
}
},
child: Text('Check'),
)final _formKey = GlobalKey<FormState>(); Form( key: _formKey, child: Column( children: [ TextFormField( validator: (value) => (value ?? '').length < 3 ? 'Too short' : null, ), ElevatedButton( onPressed: () { if (_formKey.currentState!.validate()) { _formKey.currentState!.save(); } }, child: Text('Submit'), ), ], ), )
This app shows a form with one text input for a name. When you press Submit, it checks if the name is empty. If valid, it shows a message greeting the user.
import 'package:flutter/material.dart'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget { final _formKey = GlobalKey<FormState>(); final TextEditingController _controller = TextEditingController(); @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( appBar: AppBar(title: Text('Form and GlobalKey Example')), body: Padding( padding: EdgeInsets.all(16), child: Form( key: _formKey, child: Column( children: [ TextFormField( controller: _controller, decoration: InputDecoration(labelText: 'Enter your name'), validator: (value) { if (value == null || value.isEmpty) { return 'Name cannot be empty'; } return null; }, ), SizedBox(height: 20), ElevatedButton( onPressed: () { if (_formKey.currentState!.validate()) { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('Hello, ${_controller.text}!')), ); } }, child: Text('Submit'), ), ], ), ), ), ), ); } }
Always assign a GlobalKey<FormState> to your form to control it.
Use _formKey.currentState!.validate() to check all validators at once.
You can call _formKey.currentState!.save() to save form data after validation.
The Form widget groups input fields for easy validation and saving.
A GlobalKey lets you access the form's state anywhere in your code.
Use validators to check input and show error messages automatically.