You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter中如何在用户输入时实时验证TextFormField

Flutter实现TextFormField输入时动态验证

要实现输入时自动验证字段,无需等待提交按钮触发,直接利用Flutter官方提供的AutovalidateMode属性即可解决,以下是修改后的完整代码及关键说明:

import 'package:flutter/material.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: const HomePage(),
      theme: ThemeData(
        brightness: Brightness.dark,
      ),
    );
  }
}

class HomePage extends StatefulWidget {
  const HomePage({super.key});

  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  final _formKey = GlobalKey<FormState>();
  var isLoading = false;

  void _submit() {
    final isValid = _formKey.currentState!.validate();
    if (!isValid) {
      return;
    }
    _formKey.currentState!.save();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("Form Validation"),
        leading: const Icon(Icons.filter_vintage),
      ),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Form(
          key: _formKey,
          // 新增:设置自动验证模式
          autovalidateMode: AutovalidateMode.onUserInteraction,
          child: Column(
            children: <Widget>[
              const Text(
                "Form-Validation In Flutter ",
                style: TextStyle(fontSize: 24.0, fontWeight: FontWeight.bold),
              ),
              SizedBox(
                height: MediaQuery.of(context).size.width * 0.1,
              ),
              TextFormField(
                decoration: const InputDecoration(labelText: 'E-Mail'),
                keyboardType: TextInputType.emailAddress,
                validator: (value) {
                  if (value == null || 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: const InputDecoration(labelText: 'Password'),
                // 修正:密码字段使用正确的键盘类型
                keyboardType: TextInputType.visiblePassword,
                obscureText: true,
                validator: (value) {
                  if (value == null || value.isEmpty) {
                    return 'Enter a valid password!';
                  }
                  return null;
                },
              ),
              SizedBox(
                height: MediaQuery.of(context).size.width * 0.1,
              ),
              // 可选:替换为推荐的ElevatedButton(RaisedButton已过时)
              ElevatedButton(
                style: ElevatedButton.styleFrom(
                  padding: const EdgeInsets.symmetric(
                    vertical: 10.0,
                    horizontal: 15.0,
                  ),
                ),
                child: const Text(
                  "Submit",
                  style: TextStyle(
                    fontSize: 24.0,
                  ),
                ),
                onPressed: _submit,
              )
            ],
          ),
        ),
      ),
    );
  }
}

关键修改说明:

  1. 自动验证模式:在Form组件中添加autovalidateMode: AutovalidateMode.onUserInteraction,该模式会在用户输入文字、点击字段等交互行为时自动触发对应字段的验证,完全符合输入时动态验证的需求。
  2. 修正密码键盘类型:原代码中密码字段错误设置为TextInputType.emailAddress,改为TextInputType.visiblePassword,确保弹出适合密码输入的键盘。
  3. 过时组件替换:将RaisedButton替换为ElevatedButton,这是Flutter 2.0版本后官方推荐的按钮组件,RaisedButton已被标记为过时。

自定义验证时机(可选)

如果需要更精细的控制(比如仅在输入内容变化时验证,忽略焦点切换),可以给TextFormField添加onChanged回调手动触发验证:

// 先定义控制器
final _emailController = TextEditingController();

// 在TextFormField中添加
TextFormField(
  controller: _emailController,
  onChanged: (value) {
    // 触发整个表单验证
    _formKey.currentState?.validate();
  },
  // 其他属性...
)

不过这种方式会触发整个表单的所有字段验证,而AutovalidateMode只会验证当前交互的字段,性能更优,推荐使用前者。

内容的提问来源于stack exchange,提问作者yamini r

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 23:30:15