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

Flutter TextFormField输入不符合规则时如何在底部展示错误提示文本

Flutter 表单校验错误提示实现方案

示例图

你可以通过Flutter官方提供的Form组件配合全局Key实现需求,无需额外引入第三方依赖,具体实现代码如下:

1. 提前声明必要的变量

在页面的State类中定义表单校验Key和输入框控制器:

class RegisterPageState extends State<RegisterPage> {
  // 表单校验全局Key
  final _formKey = GlobalKey<FormState>();
  // 输入框控制器
  final TextEditingController name = TextEditingController();
  final TextEditingController secondName = TextEditingController();
  final TextEditingController email = TextEditingController();
  final TextEditingController password = TextEditingController();
  final TextEditingController confirmPassword = TextEditingController();

  // 后面是build和其他方法
}

2. 重构原有输入框UI

用Form组件包裹所有输入框,给每个TextFormField添加validator校验规则:

Form(
  key: _formKey,
  child: Column(
    children: [
      Container(
        padding: EdgeInsets.fromLTRB(10, 10, 10, 0),
        child: TextFormField(
          controller: name,
          textInputAction: TextInputAction.next,
          decoration: InputDecoration(
            prefixIcon: Icon(Icons.person),
            hintText: "First name",
            border: OutlineInputBorder(
              borderSide: BorderSide(color: Colors.purpleAccent),
              borderRadius: BorderRadius.circular(10),
            ),
          ),
          // 校验规则:姓名不能为空
          validator: (value) {
            if (value == null || value.trim().isEmpty) {
              return "请输入名字";
            }
            return null;
          },
        ),
      ),
      Container(
        padding: EdgeInsets.fromLTRB(10, 10, 10, 0),
        child: TextFormField(
          controller: secondName,
          textInputAction: TextInputAction.next,
          decoration: InputDecoration(
            prefixIcon: Icon(Icons.person),
            hintText: "Second Name",
            border: OutlineInputBorder(
              borderSide: BorderSide(color: Colors.purpleAccent),
              borderRadius: BorderRadius.circular(10),
            ),
          ),
          validator: (value) {
            if (value == null || value.trim().isEmpty) {
              return "请输入姓氏";
            }
            return null;
          },
        ),
      ),
      Container(
        padding: EdgeInsets.fromLTRB(10, 10, 10, 0),
        child: TextFormField(
          controller: email,
          textInputAction: TextInputAction.next,
          decoration: InputDecoration(
            prefixIcon: Icon(Icons.mail),
            hintText: "Email-id ",
            border: OutlineInputBorder(
              borderSide: BorderSide(color: Colors.purpleAccent),
              borderRadius: BorderRadius.circular(10),
            ),
          ),
          // 校验规则:邮箱格式合法
          validator: (value) {
            if (value == null || value.trim().isEmpty) {
              return "请输入邮箱地址";
            }
            // 邮箱正则校验
            final emailReg = RegExp(r'^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$');
            if (!emailReg.hasMatch(value.trim())) {
              return "请输入合法的邮箱地址";
            }
            return null;
          },
        ),
      ),
      Container(
        padding: EdgeInsets.fromLTRB(10, 10, 10, 0),
        child: TextFormField(
          controller: password,
          obscureText: true,
          textInputAction: TextInputAction.next,
          decoration: InputDecoration(
            prefixIcon: Icon(Icons.vpn_key),
            hintText: "Password",
            border: OutlineInputBorder(
              borderSide: BorderSide(color: Colors.purpleAccent),
              borderRadius: BorderRadius.circular(10),
            ),
          ),
          // 校验规则:密码长度不少于6位
          validator: (value) {
            if (value == null || value.trim().isEmpty) {
              return "请输入密码";
            }
            if (value.trim().length < 6) {
              return "密码长度不能少于6位";
            }
            return null;
          },
        ),
      ),
      Container(
        padding: EdgeInsets.fromLTRB(10, 10, 10, 0),
        child: TextFormField(
          controller: confirmPassword,
          obscureText: true,
          textInputAction: TextInputAction.done,
          decoration: InputDecoration(
            prefixIcon: Icon(Icons.vpn_key),
            hintText: "Confirm Password",
            border: OutlineInputBorder(
              borderSide: BorderSide(color: Colors.purpleAccent),
              borderRadius: BorderRadius.circular(10),
            ),
          ),
          // 校验规则:和密码输入一致
          validator: (value) {
            if (value == null || value.trim().isEmpty) {
              return "请确认密码";
            }
            if (value.trim() != password.text.trim()) {
              return "两次输入的密码不一致";
            }
            return null;
          },
        ),
      ),
      // 注册按钮
      SizedBox(height: 20),
      ElevatedButton(
        style: ElevatedButton.styleFrom(
          minimumSize: Size(double.infinity, 50),
          shape: RoundedRectangleBorder(
            borderRadius: BorderRadius.circular(10),
          ),
        ),
        onPressed: () {
          // 触发所有输入项校验
          if (_formKey.currentState!.validate()) {
            // 校验全部通过,执行注册逻辑
            // 此处可添加调用注册接口的代码
            ScaffoldMessenger.of(context).showSnackBar(
              SnackBar(content: Text('校验通过,正在提交注册信息'))
            );
          }
          // 校验不通过时,对应输入框会自动显示你在validator中返回的红色错误提示
        },
        child: Text('注册', style: TextStyle(fontSize: 16)),
      )
    ],
  ),
)

补充说明

如果需要自定义错误文本的样式,可以在InputDecoration中配置errorStyle参数,比如调整字体大小、颜色等:

errorStyle: TextStyle(color: Colors.red, fontSize: 12)

内容的提问来源于stack exchange,提问作者Praveen Kumar

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 13:27:04