Flutter表单管理插件formx的使用

发布于 1周前 作者 wuwangju 来自 Flutter

Flutter表单管理插件formx的使用

formx 是一个强大的Flutter表单管理插件,它提供了许多便捷的方法来管理表单状态、验证和提交。本文将详细介绍如何使用 formx 插件,并提供完整的示例代码。

1. 安装插件

首先,在 pubspec.yaml 文件中添加 formx 依赖:

dependencies:
  flutter:
    sdk: flutter
  formx: ^latest_version

然后运行 flutter pub get 来安装插件。

2. 基本用法

2.1 访问表单状态

BuildContext.formx([String? key]) 方法可以自动获取当前上下文中的 FormState,也可以通过指定键来访问多个表单中的某个特定表单的状态。

final addressState = context.formx();
// 如果有多个表单:
final addressState = context.formx('address'); 

if (addressState.validate()) {
  final map = addressState.toMap();
  addressState.save(); // 处理map数据
} else {
  throw FormxException(addressState.errorTexts);
}

你也可以为特定字段获取状态:

final emailState = context.field('email');

2.2 提交快捷方式

context.submit('address')context.trySubmit('address') 方法可以一次性完成 .validate().save().toMap() 操作。如果表单无效,则会抛出错误文本。

// 与上面的代码功能相同,但更简洁
final map = context.submit('address');
final mapOrNull = context.trySubmit('address');

建议结合 flutter_async 库来处理错误。

3. 表单状态扩展方法

FormState 的扩展方法包括:

  • .toMap({FormxOptions? options}):返回一个包含所有表单值的结构化 Map
  • .rawValues:返回未修改的 FormFieldState.value
  • .initialValues:返回未修改的 FormField.initialValue
  • .isInitial:检查是否有任何字段被初始化。
  • .hasInteractedByUser:检查用户是否已与任何字段交互。
  • .hasError:检查是否有任何字段出现错误。
  • .isValid:检查所有字段是否有效。
  • .invalids:返回所有无效字段的键列表。
  • .errorTexts:返回所有字段的错误文本。
  • .fill(Map<String, dynamic> map):根据键值对设置每个关联字段。

4. 表单状态扩展类型

FormxState 是一个内联类,重新声明了部分 FormState 方法:

  • .validate([List<String>? keys])
  • .save([List<String>? keys])
  • .reset([List<String>? keys])

这些方法不仅适用于顶层表单,还适用于嵌套表单。

5. 字段状态扩展方法

你可以通过以下方法设置字段的错误文本:

.setErrorText(String? errorText)

需要使用 Validator 类来实现。

6. 全局配置

你可以使用 Formx.setup 来设置全局选项:

Formx.setup(
  defaultTitle: 'Default Title',
  datePicker: (context) => showDatePicker(...),
  filePicker: (context) => FilePicker.platform.pickFiles(),
  filesPicker: (context) => FilePicker.platform.pickFiles(allowMultiple: true),
  fileUploader: (file) async { /* upload logic */ },
  fileDeleter: (file) async { /* delete logic */ },
);

7. 自定义验证器

Validator 类提供了一种可读且声明式的方式来定义验证规则:

TextFormField(
  validator: Validator<String>()
    ..required()
    ..email(),
);

// 或者更简洁的方式:
TextFormField(
  validator: Validator().required().email(),
);

你可以自定义错误文本:

Validator.defaultRequiredText = 'This field is required';
Validator.defaultInvalidText = 'This field is invalid';

Validator.translator = (key, errorText) => '$errorText.$key';

8. 示例代码

以下是一个完整的示例,展示了如何使用 formx 插件构建复杂的表单结构:

import 'package:flutter/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:formx/formx.dart';

void main() {
  runApp(
    const MaterialApp(
      locale: Locale('pt', 'BR'),
      supportedLocales: [Locale('pt', 'BR')],
      localizationsDelegates: GlobalMaterialLocalizations.delegates,
      home: Material(
        child: FormxExample(),
      ),
    ),
  );
}

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

  [@override](/user/override)
  Widget build(BuildContext context) {
    Validator.translator = (key, errorText) => '$errorText.$key';

    return Scaffold(
      floatingActionButton: const MyWidget(),
      floatingActionButtonLocation: FloatingActionButtonLocation.endTop,
      body: Form(
        key: const Key('user'),
        onChanged: () {
          final state = context.formx();
          print(state.toMap());
        },
        child: Center(
          child: SingleChildScrollView(
            child: Form(
              key: const Key('sub'),
              onChanged: context.debugForm,
              child: Column(
                mainAxisSize: MainAxisSize.min,
                children: [
                  TextFormField(
                    key: const Key('name'),
                    initialValue: 'John Doe',
                    validator: Validator().required().minLength(2),
                  ),
                  TextFormField(
                    key: const Key('phone'),
                    initialValue: '91982224111',
                    inputFormatters: Formatter().phone.br(),
                    validator: Validator().minWords(2),
                  ),
                  TextFormField(
                    key: const Key('email'),
                    initialValue: 'some@email.com',
                    validator: Validator().required().email(),
                  ),
                  Form(
                    key: const Key('address'),
                    onChanged: context.debugForm,
                    child: Column(
                      mainAxisSize: MainAxisSize.min,
                      children: [
                        const Text('Address:'),
                        TextFormField(
                          key: const Key('street'),
                          initialValue: 'Sesame Street',
                        ),
                        CheckboxFormField(
                          key: const Key('terms'),
                          title: const Text('I agree to the terms'),
                          validator: Validator().required(),
                        ),
                      ],
                    ),
                  ),
                  ElevatedButton(
                    onPressed: () {
                      context.submit();
                    },
                    child: const Text('Submit'),
                  ),
                ],
              ),
            ),
          ),
        ),
      ),
    );
  }
}

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

  [@override](/user/override)
  Widget build(BuildContext context) {
    return ElevatedButton(
      onPressed: () {
        print(context.formx().toMap());
      },
      child: const Text('Print Form'),
    );
  }
}

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

1 回复

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


当然,下面是一个关于如何在Flutter中使用formx插件进行表单管理的示例代码。formx是一个非常强大的表单管理库,它简化了表单状态的管理和验证。

首先,确保你已经在pubspec.yaml文件中添加了formx依赖:

dependencies:
  flutter:
    sdk: flutter
  formx: ^latest_version  # 请替换为最新版本号

然后运行flutter pub get来安装依赖。

接下来,我们创建一个简单的Flutter应用,演示如何使用formx管理表单。

主应用文件 main.dart

import 'package:flutter/material.dart';
import 'package:formx/formx.dart';
import 'login_form.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'FormX Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Scaffold(
        appBar: AppBar(
          title: Text('FormX Demo'),
        ),
        body: Padding(
          padding: const EdgeInsets.all(16.0),
          child: LoginForm(),
        ),
      ),
    );
  }
}

表单文件 login_form.dart

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

class LoginForm extends StatelessWidget {
  final _form = FBFormGroup();

  @override
  Widget build(BuildContext context) {
    return Formx(
      form: _form,
      child: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            TextFormFieldFB(
              formControl: _form.control('email'),
              decoration: InputDecoration(labelText: 'Email'),
              validators: [
                Validators.required(),
                Validators.email(),
              ],
            ),
            SizedBox(height: 16),
            TextFormFieldFB(
              formControl: _form.control('password'),
              decoration: InputDecoration(labelText: 'Password'),
              obscureText: true,
              validators: [
                Validators.required(),
                Validators.minLength(6),
              ],
            ),
            SizedBox(height: 16),
            ElevatedButton(
              onPressed: () async {
                if (await _form.validate()) {
                  // 处理表单提交
                  print('Form submitted with data: $_form.value');
                }
              },
              child: Text('Login'),
            ),
          ],
        ),
      ),
    );
  }
}

解释

  1. main.dart 文件定义了应用程序的主结构和导航。
  2. login_form.dart 文件定义了登录表单。
  3. FBFormGroup 用于管理表单的状态和验证。
  4. TextFormFieldFBformx提供的一个包装器,它使得与TextFormField的集成变得简单。
  5. formControl 属性用于将TextFormFieldFBFBFormGroup中的特定字段关联起来。
  6. validators 属性用于定义验证规则,例如Validators.required()Validators.email()
  7. 在按钮的onPressed回调中,调用_form.validate()来验证表单,如果验证通过,则处理表单提交。

这个示例展示了如何使用formx来简化Flutter中的表单管理和验证。你可以根据需要扩展和修改这个示例。

回到顶部