Flutter 表单校验动态实现

在Flutter中如何动态实现表单校验?比如根据用户输入的不同内容,实时变化校验规则。比如输入邮箱时校验邮箱格式,输入手机号时校验手机号格式。目前我尝试使用Form和TextFormField,但只能在提交时统一校验,无法做到动态切换校验逻辑。有没有办法在用户输入过程中,根据输入内容类型(如检测到@符号自动切换为邮箱校验)实时改变校验规则?最好能提供代码示例或思路。

3 回复

在 Flutter 中实现表单校验可以使用 Form 和 TextFormField。动态校验可以通过给 TextFormField 设置 validator 函数来实现。

首先创建一个 FormState 对象,然后为每个 TextFormField 定义 validator 函数,这些函数接收输入值并返回 null 表示合法,返回字符串表示非法并附带错误提示。

例如:

Form(
  key: _formKey,
  child: Column(
    children: [
      TextFormField(
        validator: (value) {
          if (value.isEmpty) return '不可为空';
          if (!RegExp(r'^[a-zA-Z0-9_]+$').hasMatch(value)) 
            return '仅允许字母、数字和下划线';
          return null;
        },
      ),
      ElevatedButton(
        onPressed: () {
          if (_formKey.currentState.validate()) {
            // 提交表单
          }
        },
        child: Text('提交'),
      )
    ],
  ),
)

要实现动态校验,可以定义多个 validator 函数,根据条件动态切换它们。例如通过变量 controlType 来决定校验规则:

validator: controlType == 1 ? validator1 : validator2,

这样就能根据业务需求动态调整表单的校验逻辑了。

更多关于Flutter 表单校验动态实现的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


实现Flutter表单的动态校验可以借助Form和FormField。首先定义一个全局FormKey:

final _formKey = GlobalKey<FormState>();

然后创建表单字段,使用TextFormField,并设置validator:

TextFormField(
  validator: (value) {
    if (value!.isEmpty) {
      return '不可为空';
    }
    return null;
  },
),

动态校验需要监听输入变化。可以通过 TextEditingController监听:

final emailController = TextEditingController();

TextFormField(
  controller: emailController,
  validator: (value) {
    if (value!.isEmpty) {
      return '邮箱不能为空';
    }
    if (!RegExp(r"^[a-zA-Z0-9.]+@[a-zA-Z0-9]+\.[a-zA-Z]+").hasMatch(value)) {
      return '请输入有效邮箱';
    }
    return null;
  },
)

最后在提交时调用_formKey.currentState.validate()进行校验:

if (_formKey.currentState!.validate()) {
  // 校验通过逻辑
}

这样可以根据不同条件动态调整校验规则。

在 Flutter 中实现动态表单校验可以使用 TextFormField 配合 Form 组件,结合验证器(validator)来实现。下面是一个动态表单校验的示例:

import 'package:flutter/material.dart';

class DynamicFormValidation extends StatefulWidget {
  @override
  _DynamicFormValidationState createState() => _DynamicFormValidationState();
}

class _DynamicFormValidationState extends State<DynamicFormValidation> {
  final _formKey = GlobalKey<FormState>();
  final List<Map<String, dynamic>> formFields = [
    {
      'label': '用户名',
      'key': 'username',
      'validator': (value) {
        if (value == null || value.isEmpty) {
          return '请输入用户名';
        }
        if (value.length < 4) {
          return '用户名至少4个字符';
        }
        return null;
      }
    },
    {
      'label': '密码',
      'key': 'password',
      'validator': (value) {
        if (value == null || value.isEmpty) {
          return '请输入密码';
        }
        if (value.length < 6) {
          return '密码至少6个字符';
        }
        return null;
      },
      'obscureText': true,
    },
    {
      'label': '邮箱',
      'key': 'email',
      'validator': (value) {
        if (value == null || value.isEmpty) {
          return '请输入邮箱';
        }
        if (!RegExp(r'^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$').hasMatch(value)) {
          return '请输入有效的邮箱';
        }
        return null;
      }
    },
  ];

  Map<String, String> formData = {};

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('动态表单校验')),
      body: Form(
        key: _formKey,
        child: Padding(
          padding: EdgeInsets.all(16.0),
          child: Column(
            children: [
              ...formFields.map((field) => TextFormField(
                decoration: InputDecoration(labelText: field['label']),
                obscureText: field['obscureText'] ?? false,
                validator: field['validator'],
                onSaved: (value) => formData[field['key']] = value ?? '',
              )).toList(),
              SizedBox(height: 20),
              ElevatedButton(
                onPressed: () {
                  if (_formKey.currentState!.validate()) {
                    _formKey.currentState!.save();
                    print(formData);
                    // 提交表单数据
                  }
                },
                child: Text('提交'),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

关键点说明:

  1. 使用 Form 组件包裹所有表单字段
  2. 每个 TextFormField 都有对应的 validator 验证函数
  3. 动态生成表单字段,便于扩展
  4. 点击提交按钮时,先验证所有字段,验证通过后保存数据
  5. 可自定义每个字段的验证规则和显示方式

这种方式可以灵活地添加/删除表单字段,修改验证规则,非常适合复杂表单场景。

回到顶部