建立具有驗證功能的表單
應用程式通常需要使用者在文字欄位中輸入資訊。例如,您可能需要使用者使用電子郵件地址和密碼組合登入。
為了使應用程式安全且易於使用,請檢查使用者提供的資訊是否有效。如果使用者正確填寫了表單,請處理資訊。如果使用者提交了不正確的資訊,請顯示友善的錯誤訊息,讓他們知道哪裡出錯。
在本範例中,學習如何使用以下步驟將驗證新增至具有單一文字欄位的表單
- 使用
GlobalKey
建立一個Form
。 - 新增一個帶有驗證邏輯的
TextFormField
。 - 建立一個按鈕來驗證並提交表單。
1. 使用 GlobalKey
建立一個 Form
#建立一個 Form
。Form
小工具充當群組和驗證多個表單欄位的容器。
建立表單時,請提供一個 GlobalKey
。這會為您的 Form
分配一個唯一的識別碼。它也允許您稍後驗證表單。
將表單建立為 StatefulWidget
。這允許您建立一個唯一的 GlobalKey<FormState>()
一次。然後,您可以將其儲存為變數,並在不同的點存取它。
如果您將其設為 StatelessWidget
,您需要將這個 key 儲存在某處。由於它會消耗大量資源,因此您不希望每次執行 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。 檢視原始碼 或 回報問題。