Flutter表单工具插件form_utility的使用

Flutter表单工具插件form_utility的使用

描述

form_utility 这个包提供了一组工具来简化 Flutter 中的表单处理。它包括用于表单字段和验证的类,以及一个用于表单管理的混入(mixin)。该包设计得非常灵活和可扩展,允许你根据需要定义自己的表单字段和验证规则。

安装

要使用此包,请在 pubspec.yaml 文件中添加 form_utility 作为依赖项。

dependencies:
  form_utility: ^x.y.z

然后运行 flutter pub get 来安装它。

使用

首先,在需要功能的地方添加 FormUtility 混入。

接着,你可以通过 FormUtility 混入注册字段和验证规则。FormUtility 提供了方法来注册字段和验证规则,以及验证整个表单并访问表单数据。

registerField(
  InputField(
    name: 'EmailFieldKey',
    isRequired: true,
    validators: [EmailValidator()],
  ),
);

现在你对这些字段有了控制权,并可以按你想要的方式进行验证。

你甚至可以利用跨字段验证。

registerField(
  InputField(
    name: 'ConfirmPasswordKey',
    generateCustomValidators: (formValues) {
      return [
        BaseValidator(
          errorMessage: 'Passwords do not match',
          validation: (value) => value == fields['PasswordKey']?.value,
        ),
      ];
    },
  ),
);

你可以使用预定义的验证器或创建自己的验证器,通过继承 BaseValidator 类实现。

class CustomValidator extends BaseValidator {
  CustomValidator() : super(
    errorMessage: 'your error message',
    validation: (value) => 'your validation logic',
  );
}

表单可以通过调用 validateForm 方法进行验证。如果你需要某个字段的即时验证,你需要将该字段的 hotErrorEnabled 设置为 true

验证错误信息会由 validateForm 方法返回。你也可以使用 validateField 方法来验证单个字段。

示例代码

以下是一个完整的示例代码,展示了如何使用 form_utility 包来处理表单。

import 'package:flutter/material.dart';
import 'package:form_utility/form_utility.dart';

void main() {
  runApp(const MyApp());
}

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

  // 这个小部件是你的应用的根节点。
  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: '表单工具演示',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const MyHomePage(title: '表单工具演示'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});
  final String title;

  [@override](/user/override)
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> with FormUtility {
  static const String _emailKey = 'email';
  static const String _passwordKey = 'password';
  static const String _confirmPasswordKey = 'confirmPassword';

  String? _emailFieldErrorMessage;
  String? _passwordFieldErrorMessage;
  String? _confirmPasswordFieldErrorMessage;

  [@override](/user/override)
  void initState() {
    registerField(
      InputField(
          name: _emailKey,
          hotErrorEnabled: false,
          isRequired: true,
          validators: [EmailValidator()]),
    );
    registerField(
      InputField(
          name: _passwordKey,
          isRequired: true,
          hotErrorEnabled: true,
          validators: [MinLengthValidator(6, fieldName: 'Password')]),
    );
    registerField(
      InputField(
          name: _confirmPasswordKey,
          isRequired: true,
          hotErrorEnabled: true,
          generateCustomValidators: (fields) {
            return [
              BaseValidator(
                errorMessage: 'Passwords do not match',
                validation: (value) => value == fields[_passwordKey]?.value,
              ),
            ];
          }),
    );
    super.initState();
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            SizedBox(
              width: 200,
              child: TextField(
                onChanged: (text) {
                  updateField(_emailKey, text);
                },
                decoration: InputDecoration(
                  errorText: _emailFieldErrorMessage,
                  label: const Text('Email'),
                ),
              ),
            ),
            const SizedBox(height: 20),
            SizedBox(
              width: 200,
              child: TextField(
                onChanged: (text) {
                  updateField(_passwordKey, text);
                  setState(() {
                    _passwordFieldErrorMessage = getField(_passwordKey).error;
                  });
                },
                decoration: InputDecoration(
                  errorText: _passwordFieldErrorMessage,
                  label: const Text('Password'),
                ),
              ),
            ),
            const SizedBox(height: 20),
            SizedBox(
              width: 200,
              child: TextField(
                onChanged: (text) {
                  updateField(_confirmPasswordKey, text);
                  setState(() {
                    _confirmPasswordFieldErrorMessage =
                        getField(_confirmPasswordKey).error;
                  });
                },
                decoration: InputDecoration(
                  errorText: _confirmPasswordFieldErrorMessage,
                  label: const Text('Confirm Password'),
                ),
              ),
            ),
            const SizedBox(height: 20),
            ElevatedButton(
                onPressed: () {
                  setState(() {
                    _emailFieldErrorMessage = validateField(_emailKey);
                    _passwordFieldErrorMessage = validateField(_passwordKey);
                  });
                  if (_emailFieldErrorMessage != null &&
                      _passwordFieldErrorMessage != null) {
                    return;
                  } else {
                    // 提交表单
                  }
                },
                child: const Text('提交'))
          ],
        ),
      ),
    );
  }
}

更多关于Flutter表单工具插件form_utility的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter表单工具插件form_utility的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是一个关于如何在Flutter项目中使用form_utility插件的示例代码。请注意,form_utility并不是一个广泛知名的官方或社区维护的Flutter插件,因此这个示例假设了一个可能的API设计,以便展示如何在一个表单中使用它。如果form_utility插件实际上存在并且有不同的API,你需要根据实际的文档进行调整。

首先,假设form_utility提供了一些便利方法来验证和处理表单数据,我们可以创建一个模拟的FormUtility类来演示其功能。在实际使用中,你应该根据插件的实际API来实现。

模拟的FormUtility

class FormUtility {
  // 模拟验证函数,验证电子邮件格式
  static bool validateEmail(String email) {
    final RegExp emailRegex = RegExp(
        r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$');
    return emailRegex.hasMatch(email);
  }

  // 模拟验证函数,验证密码长度
  static bool validatePassword(String password) {
    return password.length >= 6;
  }

  // 模拟收集表单数据
  static Map<String, String> collectFormData({
    required String email,
    required String password,
  }) {
    return {
      'email': email,
      'password': password,
    };
  }
}

使用FormUtility的Flutter表单

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Form Utility Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: FormScreen(),
    );
  }
}

class FormScreen extends StatefulWidget {
  @override
  _FormScreenState createState() => _FormScreenState();
}

class _FormScreenState extends State<FormScreen> {
  final _formKey = GlobalKey<FormState>();
  String? _email;
  String? _password;
  String? _errorMessage;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Form Utility Demo'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Form(
          key: _formKey,
          child: Column(
            children: [
              TextFormField(
                decoration: InputDecoration(labelText: 'Email'),
                validator: (value) {
                  if (!FormUtility.validateEmail(value!)) {
                    return 'Please enter a valid email address.';
                  }
                  return null;
                },
                onSaved: (value) {
                  _email = value;
                },
              ),
              TextFormField(
                decoration: InputDecoration(labelText: 'Password'),
                obscureText: true,
                validator: (value) {
                  if (!FormUtility.validatePassword(value!)) {
                    return 'Password must be at least 6 characters long.';
                  }
                  return null;
                },
                onSaved: (value) {
                  _password = value;
                },
              ),
              SizedBox(height: 20),
              ElevatedButton(
                onPressed: () async {
                  if (_formKey.currentState!.validate()) {
                    _formKey.currentState!.save();

                    // 使用FormUtility收集表单数据
                    final formData = FormUtility.collectFormData(
                      email: _email!,
                      password: _password!,
                    );

                    // 在这里处理表单数据,例如发送到服务器
                    print('Form Data: $formData');

                    // 显示成功信息或进行下一步操作
                    setState(() {
                      _errorMessage = null;
                    });
                    // 例如:Navigator.pushNamed(context, '/success');
                  } else {
                    setState(() {
                      _errorMessage = 'Please fix the errors in the form.';
                    });
                  }
                },
                child: Text('Submit'),
              ),
              if (_errorMessage != null)
                Text(
                  _errorMessage!,
                  style: TextStyle(color: Colors.red),
                ),
            ],
          ),
        ),
      ),
    );
  }
}

说明

  1. 模拟的FormUtility:这个类包含了一些静态方法,用于验证电子邮件和密码,以及收集表单数据。
  2. Flutter表单:在FormScreen组件中,我们创建了一个包含两个TextFormField的表单,一个用于电子邮件输入,另一个用于密码输入。
  3. 验证和保存:在提交按钮的onPressed回调中,我们首先验证表单字段,如果验证通过,则保存表单数据并使用FormUtility收集这些数据。
  4. 错误处理:如果表单验证失败,我们显示一个错误消息。

请注意,这个示例是基于假设的form_utility插件功能创建的。如果你使用的是实际的form_utility插件,你需要根据插件的文档来调整代码。

回到顶部