构建带验证的表单
应用通常需要用户在文本字段中输入信息。例如,你可能需要用户使用电子邮件地址和密码组合登录。
为了使应用程序安全且易于使用,请检查用户提供的信息是否有效。如果用户正确填写了表单,则处理信息。如果用户提交了错误的信息,则显示一条友好的错误消息,让他们知道哪里出错了。
在本示例中,学习如何使用以下步骤向包含单个文本字段的表单添加验证。
- 使用
GlobalKey
创建一个Form
。 - 添加一个带有验证逻辑的
TextFormField
。 - 创建一个按钮来验证并提交表单。
1. 使用GlobalKey
创建一个Form
#创建一个Form
。Form
小部件充当用于对多个表单字段进行分组和验证的容器。
创建表单时,提供一个GlobalKey
。这为您的Form
分配了一个唯一标识符。它还允许您稍后验证表单。
将表单创建为StatefulWidget
。这允许您只创建一次唯一的GlobalKey<FormState>()
。然后,您可以将其存储为变量并在不同的地方访问它。
如果您将其设置为StatelessWidget
,则需要将此键存储在某个地方。由于它会消耗资源,因此您不希望在每次运行build
方法时都生成一个新的GlobalKey
。
import 'package:flutter/material.dart';
// Define a custom Form widget.
class MyCustomForm extends StatefulWidget {
const MyCustomForm({super.key});
@override
MyCustomFormState createState() {
return MyCustomFormState();
}
}
// Define a corresponding State class.
// This class holds data related to the form.
class MyCustomFormState extends State<MyCustomForm> {
// Create a global key that uniquely identifies the Form widget
// and allows validation of the form.
//
// Note: This is a `GlobalKey<FormState>`,
// not a GlobalKey<MyCustomFormState>.
final _formKey = GlobalKey<FormState>();
@override
Widget build(BuildContext context) {
// Build a Form widget using the _formKey created above.
return Form(
key: _formKey,
child: const Column(
children: <Widget>[
// Add TextFormFields and ElevatedButton here.
],
),
);
}
}
2. 添加一个带有验证逻辑的TextFormField
#虽然Form
已经就位,但它没有提供用户输入文本的方式。TextFormField
负责这项工作。TextFormField
小部件呈现一个Material Design文本字段,并在发生验证错误时显示验证错误。
通过向TextFormField
提供一个validator()
函数来验证输入。如果用户的输入无效,则validator
函数将返回包含错误消息的String
。如果没有错误,则验证器必须返回null。
对于此示例,创建一个validator
以确保TextFormField
不为空。如果为空,则返回一条友好的错误消息。
TextFormField(
// The validator receives the text that the user has entered.
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter some text';
}
return null;
},
),
3. 创建一个按钮来验证并提交表单
#现在您有了带有文本字段的表单,请提供一个按钮,用户可以点击该按钮提交信息。
当用户尝试提交表单时,检查表单是否有效。如果有效,则显示成功消息。如果无效(文本字段没有内容),则显示错误消息。
ElevatedButton(
onPressed: () {
// Validate returns true if the form is valid, or false otherwise.
if (_formKey.currentState!.validate()) {
// If the form is valid, display a snackbar. In the real world,
// you'd often call a server or save the information in a database.
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Processing Data')),
);
}
},
child: const Text('Submit'),
),
这是如何工作的?
#要验证表单,请使用步骤1中创建的_formKey
。您可以使用_formKey.currentState
访问器来访问FormState
,Flutter在构建Form
时会自动创建它。
FormState
类包含validate()
方法。当调用validate()
方法时,它会为表单中的每个文本字段运行validator()
函数。如果一切正常,则validate()
方法返回true
。如果任何文本字段包含错误,则validate()
方法将重新构建表单以显示任何错误消息,并返回false
。
交互式示例
#import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
const appTitle = 'Form Validation Demo';
return MaterialApp(
title: appTitle,
home: Scaffold(
appBar: AppBar(
title: const Text(appTitle),
),
body: const MyCustomForm(),
),
);
}
}
// Create a Form widget.
class MyCustomForm extends StatefulWidget {
const MyCustomForm({super.key});
@override
MyCustomFormState createState() {
return MyCustomFormState();
}
}
// Create a corresponding State class.
// This class holds data related to the form.
class MyCustomFormState extends State<MyCustomForm> {
// Create a global key that uniquely identifies the Form widget
// and allows validation of the form.
//
// Note: This is a GlobalKey<FormState>,
// not a GlobalKey<MyCustomFormState>.
final _formKey = GlobalKey<FormState>();
@override
Widget build(BuildContext context) {
// Build a Form widget using the _formKey created above.
return Form(
key: _formKey,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
TextFormField(
// The validator receives the text that the user has entered.
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter some text';
}
return null;
},
),
Padding(
padding: const EdgeInsets.symmetric(vertical: 16),
child: ElevatedButton(
onPressed: () {
// Validate returns true if the form is valid, or false otherwise.
if (_formKey.currentState!.validate()) {
// If the form is valid, display a snackbar. In the real world,
// you'd often call a server or save the information in a database.
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Processing Data')),
);
}
},
child: const Text('Submit'),
),
),
],
),
);
}
}
要了解如何检索这些值,请查看检索文本字段的值食谱。
除非另有说明,否则本网站上的文档反映了Flutter的最新稳定版本。页面上次更新于 2024-07-16。 查看源代码 或 报告问题。