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

Flutter TextFormField如何实现邮箱输入必含@和.的校验规则

Flutter TextFormField 邮箱格式校验实现方案

直接在现有代码基础上补充逻辑即可,不需要重构现有功能,核心是区分「格式错误」「邮箱已占用」两种错误状态,保证提示优先级和状态联动正确。

1. 新增格式校验判断方法

先写基础的格式判断函数,匹配要求的校验规则:输入必须同时包含@和.,同时排除明显的边界异常情况:

/// 校验邮箱格式是否符合要求
bool checkEmailFormatValid(String input) {
  // 核心规则:必须包含@和.
  if (!input.contains('@') || !input.contains('.')) {
    return false;
  }
  final int atPos = input.indexOf('@');
  final int lastDotPos = input.lastIndexOf('.');
  // 边界校验:@不能在开头、.不能在结尾、@必须在.前面
  return atPos > 0 && lastDotPos < input.length - 1 && atPos < lastDotPos;
}

2. 补充状态变量与联动逻辑

在组件状态类里新增一个格式错误的标识位,和已有的isEmailInvalid(邮箱已占用)、isEmailvalid(校验通过)状态联动:

// 新增状态:标记邮箱格式是否错误
bool isEmailFormatError = false;

3. 修改TextFormField对应逻辑

调整onChanged、decoration配置,补充validator属性适配Form表单校验场景,修改后的完整代码如下:

TextFormField(
    keyboardType: TextInputType.emailAddress,
    inputFormatters: [
        FilteringTextInputFormatter.allow(
            RegExp("[a-z0-9@._-]")),
    ],
    // 适配Form表单的校验逻辑
    validator: (val) {
      if (val == null || !checkEmailFormatValid(val)) {
        return "You should enter valid email address";
      }
      if (isEmailInvalid) {
        return "Email is already taken";
      }
      return null;
    },
    onChanged: (text) {
      setState(() {
        // 每次输入先校验格式
        isEmailFormatError = !checkEmailFormatValid(text);
        if (isEmailFormatError) {
          // 格式错误时重置占用状态,不触发查重请求
          isEmailInvalid = false;
        } else {
          // 仅格式合法时才触发查重逻辑,减少无效接口调用
          _onSearchChanged(text);
        }
        // 更新通过状态:格式合法 + 未被占用
        isEmailvalid = !isEmailFormatError && !isEmailInvalid;
      });
    },
    controller: emailController,
    decoration: InputDecoration(
        // 错误提示优先级:格式错误 > 邮箱已占用
        errorText: isEmailFormatError
            ? "You should enter valid email address"
            : (isEmailInvalid ? "Email is already taken" : null),
        hintText: 'Enter your email',
        // 仅双条件满足时显示绿色通过对勾
        suffixIcon: isEmailvalid
            ? const Icon(
                Icons.check,
                color: Colors.green,
              )
            : const Icon(
                Icons.check_circle,
                color: Colors.transparent)
    )),

逻辑说明

  • 输入内容缺少@或.时,会立即显示格式错误提示,不会触发邮箱查重请求
  • 格式校验通过后才会走原有的邮箱占用校验逻辑,避免无效接口调用
  • 只有格式正确、且邮箱未被占用两个条件同时满足时,才会显示绿色对勾的通过图标
  • 如果你用Form组件包裹输入框,调用表单校验方法时会自动触发validator逻辑,和手动控制的提示状态不冲突

内容的提问来源于stack exchange,提问作者Dimas Satrya

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 16:57:48