Flutter表单构建辅助展示插件form_builder_companion_presenter的使用

Flutter表单构建辅助展示插件form_builder_companion_presenter的使用

简介

form_builder_companion_presenter 是一个用于简化 Flutter 表单构建工作的插件。它通过与 form_companion_generator 的结合,帮助开发者轻松管理表单逻辑并减少样板代码。如果你不使用 Flutter FormBuilder,可以考虑使用它的兄弟插件 form_companion_presenter,后者适用于 Flutter 内置的 Form


特性

  • 减少样板代码:借助 form_companion_generator,你可以告别重复的代码。
  • 分离关注点:将 UI 和业务逻辑分离,并使它们易于测试。
  • 自动化功能
    • 自动启用提交按钮(当没有验证错误时)。
    • 支持多个验证器组合。
  • 异步验证支持:带有节流和取消功能。
  • 最佳实践:无需手动处理 onSaveonChange,也不用担心 TextControllerKey
  • 状态恢复:支持 State restoration

开始使用

安装

在你的 pubspec.yaml 文件中添加依赖项:

dependencies:
  riverpod: # 填写你偏好的版本号,高于 2.0.0
  riverpod_annotation: # 填写你偏好的版本号
  form_builder_companion_presenter: # 填写你偏好的版本号
  ...

dev_dependencies:
  build_runner: # 填写你偏好的版本号,高于 2.0.0
  riverpod_generator: # 填写你偏好的版本号
  form_companion_generator: # 填写你偏好的版本号

运行以下命令安装依赖:

flutter pub get
# 或者
flutter pub add form_builder_companion_presenter

可选步骤:在项目根目录下创建 build.yaml 文件以配置生成器(参见 build_config 文档form_companion_generator 文档)。


使用步骤

1. 声明 Presenter 类

在文件顶部声明一个 Presenter 类:

@riverpod
@formCompanion
class MyPresenter extends _$MyPresenter {
  MyPresenter() {
  }

  [@override](/user/override)
  FutureOr<MyPresenterFormProperties> build() async {
  }
}
2. 添加混入类

为 Presenter 添加 CompanionPresenterMixinFormBuilderCompanionMixin 混入类:

@riverpod
@formCompanion
class MyPresenter extends _$MyPresenter
  with CompanionPresenterMixin, FormBuilderCompanionMixin {
  MyPresenter() {
  }

  [@override](/user/override)
  FutureOr<MyPresenterFormProperties> build() async {
  }
}
3. 初始化属性

在构造函数中调用 initializeCompanionMixin 方法来初始化属性。这些属性表示表单字段的状态值:

MyPresenter() {
  initializeCompanionMixin(
    PropertyDescriptorBuilder()
    ..add<String>(
      name: 'name',
      validatorFactories: [
        (context) => FormBuilderValidators.required,
      ],
    )
    ..add<String>(
      name: 'age',
      validatorFactories: [
        (context) => FormBuilderValidators.required,
        (context) => (value) => int.parse(value!) < 0 ? 'Age must not be negative.' : null,
      ],
    )
  );
}

注意:PropertyDescriptorBuilder 提供了多种扩展方法来简化初始化过程。

4. 实现 build 方法

从上游状态中获取初始数据,并将其填充到属性中:

[@override](/user/override)
FutureOr<MyPresenterFormProperties> build() async {
  final upstreamState = await ref.watch(upstreamStateProvider.future);
  return resetProperties(
    (properties.copyWith()
    ..name(upstreamState.name)
    ..age(upstreamState.age)
    ).build()
  );
}
5. 添加部分指令

在文件顶部添加 part 指令:

part 'example.fcp.dart';
part 'example.g.dart';
6. 运行代码生成器

运行以下命令以生成代码:

flutter pub run build_runner build -d

这将生成 riverpod 提供器和相关的类型。

7. 实现提交逻辑

在 Presenter 中实现 doSubmit 方法以处理整个表单的提交操作:

[@override](/user/override)
FutureOr<void> doSubmit(BuildContext context) async {
  // 获取经过验证的输入值
  String name = properties.values.name;
  int age = properties.values.age;

  // 调用业务逻辑(可以使用 await)
  ...

  // 更新状态以暴露给其他组件
  ref.read(anotherStateProvider).state = AsyncData(MyState(name: name, age: age));
}
8. 创建表单 UI

创建一个包含表单字段的 Widget。我们使用 ConsumerWidget 来绑定 Presenter:

class MyForm extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) => FormBuilder(
    child: MyFormFields(),
  );
}

class MyFormFields extends ConsumerWidget {
  [@override](/user/override)
  Widget build(BuildContext context, WidgetRef ref) {
    return Column(
      children: [
        state.value.fields.name(context),
        state.value.fields.age(context),
        ElevatedButton(
          onPressed: state.value.submit(context),
          child: Text('Submit'),
        ),
      ],
    );
  }
}

如果启用了 AutovalidateMode.disabled(默认值),可以在 doSubmit() 方法头部执行验证:

[@override](/user/override)
FutureOr<void> doSubmit(BuildContext context) async{
  if (!await validateAndSave(context)) {
    return;
  }

  // 继续处理表单提交逻辑
}

启用状态恢复

为了提升用户体验,可以通过 FormPropertiesRestorationScope 来启用状态恢复。这样即使应用被后台杀死,用户也能恢复之前填写的内容。

class MyForm extends ConsumerWidget {
  [@override](/user/override)
  Widget build(BuildContext context, WidgetRef ref) {
    final presenter = ref.read(myPresenterProvider.notifier);
    return FormBuilder(
      child: FormPropertiesRestorationScope(
        presenter: presenter,
        child: MyFormFields(),
      ),
    );
  }
}

更多关于Flutter表单构建辅助展示插件form_builder_companion_presenter的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter表单构建辅助展示插件form_builder_companion_presenter的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


form_builder_companion_presenter 是一个用于 Flutter 的插件,它可以帮助开发者更轻松地构建和展示表单。这个插件通常与 flutter_form_builder 插件一起使用,flutter_form_builder 是一个强大的表单构建库,而 form_builder_companion_presenter 则提供了额外的功能来展示表单数据。

安装

首先,你需要在 pubspec.yaml 文件中添加依赖:

dependencies:
  flutter:
    sdk: flutter
  flutter_form_builder: ^7.0.0
  form_builder_companion_presenter: ^1.0.0

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

基本使用

  1. 导入包

    import 'package:flutter_form_builder/flutter_form_builder.dart';
    import 'package:form_builder_companion_presenter/form_builder_companion_presenter.dart';
    
  2. 创建表单

    使用 FormBuilder 创建一个表单,并定义表单字段。

    final _formKey = GlobalKey<FormBuilderState>();
    
    FormBuilder(
      key: _formKey,
      child: Column(
        children: [
          FormBuilderTextField(
            name: 'name',
            decoration: InputDecoration(labelText: 'Name'),
          ),
          FormBuilderTextField(
            name: 'email',
            decoration: InputDecoration(labelText: 'Email'),
          ),
          // 添加更多字段...
        ],
      ),
    );
    
  3. 使用 FormBuilderCompanionPresenter

    在表单提交后,使用 FormBuilderCompanionPresenter 来展示表单数据。

    ElevatedButton(
      onPressed: () {
        if (_formKey.currentState!.saveAndValidate()) {
          final formData = _formKey.currentState!.value;
          showDialog(
            context: context,
            builder: (context) {
              return AlertDialog(
                content: FormBuilderCompanionPresenter(
                  formData: formData,
                ),
              );
            },
          );
        }
      },
      child: Text('Submit'),
    );
    

自定义展示

FormBuilderCompanionPresenter 允许你自定义表单数据的展示方式。你可以通过传递 builder 参数来自定义展示内容。

FormBuilderCompanionPresenter(
  formData: formData,
  builder: (context, formData) {
    return Column(
      children: formData.entries.map((entry) {
        return ListTile(
          title: Text(entry.key),
          subtitle: Text(entry.value.toString()),
        );
      }).toList(),
    );
  },
);

其他功能

form_builder_companion_presenter 还提供了其他一些功能,比如:

  • 字段类型识别:自动识别字段类型并展示相应的图标或样式。
  • 数据格式化:支持对日期、数字等类型的数据进行格式化展示。

示例

以下是一个完整的示例,展示了如何使用 form_builder_companion_presenter 来构建和展示表单:

import 'package:flutter/material.dart';
import 'package:flutter_form_builder/flutter_form_builder.dart';
import 'package:form_builder_companion_presenter/form_builder_companion_presenter.dart';

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

class MyApp extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text('Form Builder Companion Presenter')),
        body: MyForm(),
      ),
    );
  }
}

class MyForm extends StatelessWidget {
  final _formKey = GlobalKey<FormBuilderState>();

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.all(16.0),
      child: Column(
        children: [
          FormBuilder(
            key: _formKey,
            child: Column(
              children: [
                FormBuilderTextField(
                  name: 'name',
                  decoration: InputDecoration(labelText: 'Name'),
                ),
                FormBuilderTextField(
                  name: 'email',
                  decoration: InputDecoration(labelText: 'Email'),
                ),
                // 添加更多字段...
              ],
            ),
          ),
          SizedBox(height: 20),
          ElevatedButton(
            onPressed: () {
              if (_formKey.currentState!.saveAndValidate()) {
                final formData = _formKey.currentState!.value;
                showDialog(
                  context: context,
                  builder: (context) {
                    return AlertDialog(
                      content: FormBuilderCompanionPresenter(
                        formData: formData,
                      ),
                    );
                  },
                );
              }
            },
            child: Text('Submit'),
          ),
        ],
      ),
    );
  }
}
回到顶部