flutter-form
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseFlutter Form Validation
Flutter 表单验证
Goal
目标
Implements stateful form validation in Flutter using , , and . Manages validation state efficiently without unnecessary key regeneration and handles user input validation workflows. Assumes a pre-existing Flutter environment with Material Design dependencies available.
FormTextFormFieldGlobalKey<FormState>在Flutter中使用、和实现有状态的表单验证。高效管理验证状态,避免不必要的键重新生成,并处理用户输入验证流程。假设已存在具备Material Design依赖的Flutter环境。
FormTextFormFieldGlobalKey<FormState>Decision Logic
决策逻辑
When implementing form validation, follow this decision tree to determine the flow of state and UI updates:
- User triggers submit action:
- Call .
_formKey.currentState!.validate()
- Call
- Does return
validate()?true- Yes (Valid): Proceed with data processing (e.g., API call, local storage). Trigger success UI feedback (e.g., , navigation).
SnackBar - No (Invalid): The automatically rebuilds the
FormStatewidgets to display theTextFormFielderror messages returned by their respectiveStringfunctions. Halt submission.validator
- Yes (Valid): Proceed with data processing (e.g., API call, local storage). Trigger success UI feedback (e.g.,
在实现表单验证时,请遵循以下决策树来确定状态和UI更新流程:
- 用户触发提交操作:
- 调用。
_formKey.currentState!.validate()
- 调用
- 是否返回
validate()?true- 是(有效): 继续进行数据处理(例如API调用、本地存储)。触发成功UI反馈(例如、页面导航)。
SnackBar - 否(无效): 会自动重建
FormState组件,以显示各自TextFormField函数返回的错误提示字符串。终止提交流程。validator
- 是(有效): 继续进行数据处理(例如API调用、本地存储)。触发成功UI反馈(例如
Instructions
操作步骤
-
Initialize the Stateful Form Container Create ato hold the form. Instantiate a
StatefulWidgetexactly once within theGlobalKey<FormState>class to prevent resource-expensive key regeneration duringStatecycles.builddartimport 'package:flutter/material.dart'; class CustomValidatedForm extends StatefulWidget { const CustomValidatedForm({super.key}); State<CustomValidatedForm> createState() => _CustomValidatedFormState(); } class _CustomValidatedFormState extends State<CustomValidatedForm> { // Instantiate the GlobalKey once in the State object final _formKey = GlobalKey<FormState>(); Widget build(BuildContext context) { return Form( key: _formKey, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: <Widget>[ // Form fields will be injected here ], ), ); } } -
Implement TextFormFields with Validation Logic Injectwidgets into the
TextFormField's widget tree. Provide aFormfunction for each field.validatordartTextFormField( decoration: const InputDecoration( hintText: 'Enter your email', labelText: 'Email', ), validator: (String? value) { if (value == null || value.isEmpty) { return 'Please enter an email address'; } if (!value.contains('@')) { return 'Please enter a valid email address'; } // Return null if the input is valid return null; }, onSaved: (String? value) { // Handle save logic here }, ) -
Implement the Submit Action and Validation Trigger Create a button that accesses thevia the
FormStateto trigger validation.GlobalKeydartPadding( padding: const EdgeInsets.symmetric(vertical: 16.0), child: ElevatedButton( onPressed: () { // Validate returns true if the form is valid, or false otherwise. if (_formKey.currentState!.validate()) { // Save the form fields if necessary _formKey.currentState!.save(); // Provide success feedback ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('Processing Data')), ); } }, child: const Text('Submit'), ), ) -
STOP AND ASK THE USER: Pause implementation and ask the user for the following context:
- "What specific fields do you need in this form?"
- "What are the exact validation rules for each field (e.g., regex patterns, minimum lengths)?"
- "What action should occur upon successful validation (e.g., API payload submission, navigation)?"
-
Validate-and-Fix Loop After generating the form, verify the following:
- Ensure is null-checked properly using the bang operator (
_formKey.currentState!.validate()) or safe calls if the key might be detached.! - Verify that every function explicitly returns
validatoron success. Returning an empty string (null) will trigger an error state with no text.""
- Ensure
-
初始化有状态表单容器 创建一个来承载表单。在
StatefulWidget类中仅实例化一次State,以避免在GlobalKey<FormState>周期中进行资源密集型的键重新生成操作。builddartimport 'package:flutter/material.dart'; class CustomValidatedForm extends StatefulWidget { const CustomValidatedForm({super.key}); State<CustomValidatedForm> createState() => _CustomValidatedFormState(); } class _CustomValidatedFormState extends State<CustomValidatedForm> { // Instantiate the GlobalKey once in the State object final _formKey = GlobalKey<FormState>(); Widget build(BuildContext context) { return Form( key: _formKey, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: <Widget>[ // Form fields will be injected here ], ), ); } } -
实现带验证逻辑的TextFormFields 将组件注入到
TextFormField的组件树中。为每个字段提供Form函数。validatordartTextFormField( decoration: const InputDecoration( hintText: 'Enter your email', labelText: 'Email', ), validator: (String? value) { if (value == null || value.isEmpty) { return 'Please enter an email address'; } if (!value.contains('@')) { return 'Please enter a valid email address'; } // Return null if the input is valid return null; }, onSaved: (String? value) { // Handle save logic here }, ) -
实现提交操作与验证触发 创建一个按钮,通过访问
GlobalKey以触发验证。FormStatedartPadding( padding: const EdgeInsets.symmetric(vertical: 16.0), child: ElevatedButton( onPressed: () { // Validate returns true if the form is valid, or false otherwise. if (_formKey.currentState!.validate()) { // Save the form fields if necessary _formKey.currentState!.save(); // Provide success feedback ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('Processing Data')), ); } }, child: const Text('Submit'), ), ) -
暂停并询问用户: 暂停实现流程,并向用户询问以下上下文信息:
- "此表单需要包含哪些具体字段?"
- "每个字段的确切验证规则是什么(例如正则表达式、最小长度)?"
- "验证成功后应执行什么操作(例如提交API请求、页面跳转)?"
-
验证与修复循环 生成表单后,验证以下内容:
- 确保使用感叹号运算符(
_formKey.currentState!.validate())进行了正确的空检查,或者在键可能未关联时使用安全调用。! - 验证每个函数在验证通过时显式返回
validator。返回空字符串(null)会触发无文本显示的错误状态。""
- 确保
Constraints
约束条件
- DO NOT instantiate the inside the
GlobalKey<FormState>method. It must be a persistent member of thebuildclass.State - DO NOT use a for the form container unless the
StatelessWidgetis being passed down from a stateful parent.GlobalKey - DO NOT use standard widgets if you require built-in form validation; you must use
TextField(which wrapsTextFormFieldin aTextField).FormField - ALWAYS return from a
nullfunction when the input is valid.validator - ALWAYS ensure the widget is a common ancestor to all
Formwidgets that need to be validated together.TextFormField
- 请勿在方法中实例化
build。它必须是GlobalKey<FormState>类的持久成员。State - 请勿使用作为表单容器,除非
StatelessWidget是从有状态的父组件传递下来的。GlobalKey - 如果需要内置表单验证,请勿使用标准的组件;必须使用
TextField(它在TextFormField中封装了FormField)。TextField - 必须在输入有效时从函数返回
validator。null - 必须确保组件是所有需要一起验证的
Form组件的公共父组件。TextFormField