Flutter表单管理插件formi的使用

Flutter表单管理插件formi的使用

formi 是一个极简主义的表单构建器,具有空安全性和无依赖性。它受到 flutter_form_builder 的启发。

开始使用

formi 不包含UI组件,但它可以帮助你构建自己的UI,从而让你拥有 完全的控制权

你可以查看 example 文件夹,里面包含了一些组件来帮助你开始。

1. 创建一个继承自 FormiField 的小部件

例如,你可以创建一个复选框字段,如下所示:

class FormiCheckbox extends FormiField<bool> {
  final String title;
  final String? subtitle;

  FormiCheckbox({
    required this.title,
    required String name,
    this.subtitle,
    List<FormiValidator<bool>>? validators,
    bool? initialValue,
    bool? enabled = true,
  }) : super(
          name: name,
          validators: validators,
          initialValue: initialValue,
          enabled: enabled,
          builder: (field) {
            return CheckboxListTile(
              dense: true,
              title: Text(title),
              value: field.value ?? false,
              onChanged: field.didChange,
              contentPadding: EdgeInsets.zero,
            );
          },
        );
}

2. 将你的表单包装在 Formi 容器中

Formi 中的字段需要一个唯一的 name,用于保存字段的值。

Formi(
  child: Column(
    children: [
        Text('隐私偏好设置'),
        FormiCheckbox(
            name: 'strict',
            title: '严格必要',
            subtitle: '应用程序正常运行所必需',
            initialValue: true,
            enabled: false,
        ),
        FormiCheckbox(
            name: 'analytics',
            title: '分析',
            subtitle: '允许我们收集有关您如何使用应用程序的信息',
        ),
        OutlinedButton(
            child: Text('提交'),
            onPressed: () {
                final formiState = Formi.of(context);
                formiState.save();
                if (formiState.validate()) {
                    // 通过 formiState.value 获取表单状态
                }
            }
        ),
    ]
  ),
)

3. 添加自定义验证器

验证器是一个函数,该函数接受字段值和表单状态,并返回:

  • 如果有错误,则返回一个 String
  • 否则返回 null
class Validators {
  static FormiValidator<T> required<T>(BuildContext context, {String? errorText}) {
    return (value, state) {
      if (value == null ||
          (value is String && value.isEmpty) ||
          (value is Iterable && value.isEmpty) ||
          (value is Map && value.isEmpty)) {
        return errorText ?? '此字段不能为空。';
      }
      return null;
    };
  }
}

4. 创建更多符合你需要的组件

例如,提交按钮可以写成如下形式:

class FormiSubmit extends StatelessWidget {
  final Widget Function(FormiState) builder;
  FormiSubmit({required this.builder});

  [@override](/user/override)
  Widget build(BuildContext context) {
    final _formiState = Formi.of(context);
    return builder(_formiState);
  }
}

示例代码

以下是完整的示例代码:

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

class Validators {
  static FormiValidator<T> required<T>(BuildContext context, {String? errorText}) {
    return (value, state) {
      if (value == null ||
          (value is String && value.isEmpty) ||
          (value is Iterable && value.isEmpty) ||
          (value is Map && value.isEmpty)) {
        return errorText ?? '此字段不能为空。';
      }
      return null;
    };
  }
}

class FormiCheckbox extends FormiField<bool> {
  final String title;
  final String? subtitle;

  FormiCheckbox({
    required this.title,
    required String name,
    this.subtitle,
    List<FormiValidator<bool>>? validators,
    bool? initialValue,
    bool? enabled = true,
  }) : super(
          name: name,
          validators: validators,
          initialValue: initialValue,
          enabled: enabled,
          builder: (field) {
            return CheckboxListTile(
              dense: true,
              title: Text(title),
              value: field.value ?? false,
              onChanged: field.didChange,
              contentPadding: EdgeInsets.zero,
            );
          },
        );
}

class FormiSubmit extends StatelessWidget {
  final Widget Function(FormiState) builder;
  FormiSubmit({required this.builder});

  [@override](/user/override)
  Widget build(BuildContext context) {
    final _formiState = Formi.of(context);
    return builder(_formiState);
  }
}

void main() {
  runApp(
    Formi(
      child: Builder(
        builder: (context) {
          return Column(
            children: [
              Text('隐私偏好设置'),
              FormiCheckbox(
                name: 'strict',
                title: '严格必要',
                subtitle: '应用程序正常运行所必需',
                initialValue: true,
                enabled: false,
              ),
              FormiCheckbox(
                name: 'analytics',
                title: '分析',
                subtitle: '允许我们收集有关您如何使用应用程序的信息',
                validators: [Validators.required(context)],
              ),
              FormiSubmit(
                builder: (formiState) {
                  return OutlinedButton(
                    onPressed: () {
                      formiState.save();
                      if (formiState.validate()) {
                        // 通过 formiState.value 获取表单状态
                      }
                    },
                    child: Text('提交'),
                  );
                },
              )
            ],
          );
        },
      ),
    ),
  );
}

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

1 回复

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


在Flutter开发中,formi 是一个强大的表单管理插件,它能够帮助你简化表单状态的管理和验证。以下是一个简单的代码示例,展示如何在Flutter项目中使用 formi 来管理表单。

首先,确保你已经将 formi 添加到你的 pubspec.yaml 文件中:

dependencies:
  flutter:
    sdk: flutter
  formi: ^x.y.z  # 替换为最新版本号

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

接下来,我们创建一个简单的表单,包括用户名和密码字段,并使用 formi 来管理它们。

1. 导入必要的包

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

2. 定义表单模型

创建一个数据类来表示表单的数据模型:

class LoginForm extends FormModel {
  StringField username = StringField(
    validators: [Validators.required('Username is required')],
  );

  StringField password = StringField(
    validators: [Validators.required('Password is required')],
    obscureText: true,
  );
}

3. 创建UI表单

使用 Formi 小部件来构建表单UI:

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: LoginScreen(),
    );
  }
}

class LoginScreen extends StatelessWidget {
  final LoginForm form = LoginForm();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Login'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Formi(
          model: form,
          child: Column(
            children: [
              FormiField(
                field: form.username,
                builder: (field) {
                  return TextField(
                    decoration: InputDecoration(labelText: 'Username'),
                    controller: field.controller,
                  );
                },
              ),
              FormiField(
                field: form.password,
                builder: (field) {
                  return TextField(
                    decoration: InputDecoration(labelText: 'Password'),
                    controller: field.controller,
                    obscureText: field.obscureText,
                  );
                },
              ),
              FormiErrors(model: form),
              SizedBox(height: 16),
              ElevatedButton(
                onPressed: () async {
                  final result = await form.validate();
                  if (result.isValid) {
                    // 处理有效表单数据
                    print('Form is valid');
                    print('Username: ${form.username.value}');
                    print('Password: ${form.password.value}');
                  } else {
                    // 处理无效表单数据
                    print('Form is invalid');
                    print(result.errors);
                  }
                },
                child: Text('Submit'),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

4. 运行应用

现在,你可以运行你的Flutter应用,并看到一个包含用户名和密码字段的登录表单。当你尝试提交表单时,如果字段为空,将显示相应的错误消息。

这个示例展示了如何使用 formi 来管理表单字段、验证表单数据,并在UI中显示错误消息。formi 提供了许多其他功能,如自定义验证器、表单重置等,你可以根据需要进一步探索和使用这些功能。

回到顶部