Flutter表单构建扩展字段插件form_builder_extra_fields的使用

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

Flutter表单构建扩展字段插件form_builder_extra_fields的使用

简介

form_builder_extra_fields 是一个为 flutter_form_builder 包提供额外输入组件的Flutter包。它使得在表单中添加常见的预构建输入字段变得简单,而无需从头创建自己的 FormBuilderField

特性

  • flutter_form_builder 添加多种类型的输入组件。
  • 支持以下输入组件:
    • FormBuilderColorPicker:颜色选择器
    • FormBuilderRating:评分选择
    • FormBuilderSearchableDropdown:可搜索的下拉菜单
    • FormBuilderSignaturePad:签名板
    • FormBuilderTouchSpin:通过点击加减图标来选择数值
    • FormBuilderTypeAhead:自动完成用户输入(如联想输入)

参数

所有类型的输入组件都支持以下通用属性:

属性 类型 默认值 必填 描述
name String - 表单值Map中的键
initialValue T null 输入字段的初始值
enabled bool true 是否允许用户输入
decoration InputDecoration 默认样式 定义边框、标签、图标和样式
validator FormFieldValidator<T> null 检查 FormField 中值的有效性
onChanged ValueChanged<T> null 当字段值改变时触发
valueTransformer ValueTransformer<T> null 在保存到表单值之前转换字段值(例如,将文本字段的值从 String 转换为 num

使用方法

设置

安装依赖后即可直接使用,无需特别配置。

基本用法

下面是一个简单的示例代码,演示了如何在表单中使用 FormBuilderColorPickerField 组件:

final _formKey = GlobalKey<FormBuilderState>();

FormBuilder(
  key: _formKey,
  child: FormBuilderColorPickerField(
    name: 'color_picker',
  ),
)

示例Demo

这里提供了一个完整的示例应用程序,展示了如何集成多个来自 form_builder_extra_fields 的组件:

import 'package:flutter/material.dart';
import 'package:flutter_form_builder/flutter_form_builder.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:form_builder_extra_fields/form_builder_extra_fields.dart';
import 'package:form_builder_validators/form_builder_validators.dart';

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

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(primarySwatch: Colors.blue),
      localizationsDelegates: const [
        FormBuilderLocalizations.delegate,
        GlobalMaterialLocalizations.delegate,
        GlobalWidgetsLocalizations.delegate,
      ],
      supportedLocales: const [Locale('en')],
      home: const MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key});

  @override
  MyHomePageState createState() => MyHomePageState();
}

class MyHomePageState extends State<MyHomePage> {
  final _formKey = GlobalKey<FormBuilderState>();

  void _onChanged(dynamic val) => debugPrint(val.toString());

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Extra Fields Example')),
      body: SingleChildScrollView(
        child: Padding(
          padding: const EdgeInsets.all(8.0),
          child: FormBuilder(
            key: _formKey,
            onChanged: () {
              _formKey.currentState?.save();
              debugPrint(_formKey.currentState?.value.toString());
            },
            autovalidateMode: AutovalidateMode.onUserInteraction,
            child: Column(
              children: [
                // 可搜索的在线下拉菜单
                FormBuilderSearchableDropdown<String>(
                  name: 'searchable_dropdown_online',
                  onChanged: _onChanged,
                  asyncItems: (filter) async {
                    await Future.delayed(const Duration(seconds: 1));
                    return allCountries
                        .where((element) =>
                            element.toLowerCase().contains(filter.toLowerCase()))
                        .toList();
                  },
                  decoration: const InputDecoration(
                    labelText: 'Searchable Dropdown Online',
                  ),
                ),
                // 可搜索的离线下拉菜单
                FormBuilderSearchableDropdown<String>(
                  popupProps: const PopupProps.menu(showSearchBox: true),
                  dropdownSearchDecoration: const InputDecoration(
                    hintText: 'Search',
                    labelText: 'Search',
                  ),
                  name: 'searchable_dropdown_offline',
                  items: allCountries,
                  onChanged: _onChanged,
                  decoration: const InputDecoration(labelText: 'Searchable Dropdown Offline'),
                  filterFn: (country, filter) =>
                      country.toLowerCase().contains(filter.toLowerCase()),
                ),
                const SizedBox(height: 15),
                // 颜色选择器
                FormBuilderColorPickerField(
                  name: 'color_picker',
                  initialValue: Colors.yellow,
                  colorPickerType: ColorPickerType.materialPicker,
                  decoration: const InputDecoration(labelText: 'Color Picker'),
                ),
                // 自动补全文本框
                FormBuilderTypeAhead<String>(
                  decoration: const InputDecoration(
                    labelText: 'TypeAhead (Autocomplete TextField)',
                    hintText: 'Start typing country name',
                  ),
                  name: 'country',
                  onChanged: _onChanged,
                  itemBuilder: (context, country) {
                    return ListTile(title: Text(country));
                  },
                  initialValue: 'Uganda',
                  suggestionsCallback: (query) {
                    if (query.isNotEmpty) {
                      var lowercaseQuery = query.toLowerCase();
                      return allCountries.where((country) {
                        return country.toLowerCase().contains(lowercaseQuery);
                      }).toList(growable: false)
                        ..sort((a, b) => a
                            .toLowerCase()
                            .indexOf(lowercaseQuery)
                            .compareTo(
                                b.toLowerCase().indexOf(lowercaseQuery)));
                    } else {
                      return allCountries;
                    }
                  },
                ),
                // 数字增减控件
                FormBuilderTouchSpin(
                  decoration: const InputDecoration(labelText: 'TouchSpin'),
                  name: 'touch_spin',
                  initialValue: 10,
                  step: 1,
                  iconSize: 48.0,
                  addIcon: const Icon(Icons.arrow_right),
                  subtractIcon: const Icon(Icons.arrow_left),
                  onChanged: _onChanged,
                ),
                // 评分条
                FormBuilderRatingBar(
                  decoration: const InputDecoration(labelText: 'Rating Bar'),
                  name: 'rate',
                  itemSize: 32.0,
                  initialValue: 1.0,
                  maxRating: 5.0,
                  onChanged: _onChanged,
                ),
                // 签名板
                FormBuilderSignaturePad(
                  decoration: const InputDecoration(
                    labelText: 'Signature Pad',
                  ),
                  name: 'signature',
                  border: Border.all(color: Colors.green),
                  onChanged: _onChanged,
                ),
                const SizedBox(height: 10),
                Row(
                  children: <Widget>[
                    Expanded(
                      child: ElevatedButton(
                        onPressed: () {
                          if (_formKey.currentState?.saveAndValidate() ??
                              false) {
                            debugPrint(_formKey.currentState?.value.toString());
                          } else {
                            debugPrint(_formKey.currentState?.value.toString());
                            debugPrint('validation failed');
                          }
                        },
                        child: const Text('Submit'),
                      ),
                    ),
                    const SizedBox(width: 20),
                    Expanded(
                      child: OutlinedButton(
                        onPressed: () {
                          _formKey.currentState?.reset();
                        },
                        child: const Text('Reset'),
                      ),
                    ),
                  ],
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }
}

// 国家列表
const allCountries = [
  'Afghanistan', 'Albania', 'Algeria', /* ... */ 'Zimbabwe'
];

此代码段包括了不同类型的输入组件,并展示了如何将它们组合成一个完整的表单。每个组件都有其特定的功能,如颜色选择、评分、搜索选择等。此外,还提供了提交和重置按钮用于操作整个表单的数据。


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

1 回复

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


当然,下面是一个关于如何在Flutter中使用form_builder_extra_fields插件来扩展表单构建的示例代码。这个插件允许你在Flutter的表单构建器(flutter_form_builder)中添加额外的字段类型。

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

dependencies:
  flutter:
    sdk: flutter
  flutter_form_builder: ^7.0.0  # 请检查最新版本
  form_builder_validation: ^6.0.0  # 请检查最新版本
  form_builder_extra_fields: ^5.0.0  # 请检查最新版本

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

接下来,是一个完整的示例,展示如何使用form_builder_extra_fields来扩展表单构建器并添加自定义字段。在这个示例中,我们将添加一个“日期选择器”字段。

import 'package:flutter/material.dart';
import 'package:flutter_form_builder/flutter_form_builder.dart';
import 'package:form_builder_validation/form_builder_validation.dart';
import 'package:form_builder_extra_fields/form_builder_extra_fields.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Form Builder Extra Fields Example'),
        ),
        body: MyForm(),
      ),
    );
  }
}

class MyForm extends StatefulWidget {
  @override
  _MyFormState createState() => _MyFormState();
}

class _MyFormState extends State<MyForm> {
  final GlobalKey<FormBuilderState> _fbKey = GlobalKey<FormBuilderState>();

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.all(16.0),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: <Widget>[
          FormBuilder(
            key: _fbKey,
            initialValue: {
              'date_field': '',
            },
            fields: [
              FormBuilderDateField(
                name: 'date_field',
                label: 'Select Date',
                validators: [
                  FormBuilderValidators.required(errorText: 'This field is required'),
                ],
                decoration: InputDecoration(
                  border: OutlineInputBorder(),
                ),
              ),
            ],
          ),
          SizedBox(height: 20),
          ElevatedButton(
            onPressed: () {
              if (_fbKey.currentState!.validate()) {
                _fbKey.currentState!.save();
                print(_fbKey.currentState!.value);
              }
            },
            child: Text('Submit'),
          ),
        ],
      ),
    );
  }
}

在这个示例中,我们做了以下几件事:

  1. 导入必要的包:flutter_form_builderform_builder_validationform_builder_extra_fields
  2. 创建一个MyApp应用,它包含一个Scaffold,其中包含一个标题和一个MyForm组件。
  3. MyForm组件中,我们创建了一个FormBuilder组件,并使用FormBuilderDateField(这是form_builder_extra_fields插件提供的一个额外字段)来添加一个日期选择器字段。
  4. 我们还为这个字段设置了一个验证器,确保它是必填字段。
  5. 在表单下方,我们添加了一个按钮,当点击按钮时,表单会进行验证并打印出表单的值。

这个示例展示了如何使用form_builder_extra_fields插件来扩展Flutter表单构建器,并添加自定义字段。你可以根据需要添加更多类型的字段,并配置它们的验证逻辑。

回到顶部