Flutter动态表单构建插件fiona_dynamic_form的使用

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

Flutter动态表单构建插件fiona_dynamic_form的使用

功能

fiona_dynamic_form 插件可以帮助你动态创建表单。一个 DynamicForm 可以验证自身并填充所有值以创建任何对象。

入门

该插件实现了不同类型的输入字段。对于每种输入类型,你可以找到一个 FormItem 和与之关联的 FormItemWidget。要了解其思想和结构,可以参考相关文章(由于要求,此处不提供链接)。

使用方法

以下是一个完整的示例,展示了如何使用 fiona_dynamic_form 插件来创建一个动态表单。这个表单用于编辑或创建员工信息。

1. 定义 FormEmployee
import 'package:fiona_dynamic_form/fiona_dynamic_form.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';

import 'model/employee.dart';

class FormEmployee extends FionaDynamicForm {
  final Function(BuildContext context, Employee employee) onSubmit;
  final Function(BuildContext context) onCancel;

  FormEmployee(
      {required this.onSubmit, required this.onCancel, Employee? employee}) {
    // 定义姓名输入项
    FormTextItem name = FormTextItem(
        label: "姓名",
        value: employee?.name,
        formItemStyle: getInputStyle(),
        validators: [FormMaxLengthValidator(15), FormRequiredValidator()]);

    // 定义密码输入项
    FormTextItem password = FormTextItem(
        label: "密码",
        formItemStyle: getPasswordInputStyle(),
        validators: [FormRequiredValidator()]);

    // 定义出生日期输入项
    FormDatetimeItem birthday = FormDatetimeItem(
        label: "出生日期",
        withTime: false,
        value: employee?.birthday,
        formItemStyle: getInputStyle());

    // 定义最后登录时间输入项
    FormDatetimeItem lastPost = FormDatetimeItem(
        label: "最后登录时间",
        withTime: true,
        value: employee?.lastPost,
        formItemStyle: getInputStyle());

    // 定义国家选择项
    FormSelectItem country = FormSelectItem(
        label: "国家",
        value: employee?.country,
        validators: [FormRequiredValidator()],
        selectFieldController: CountryController());

    // 定义省份选择项
    FormSelectItem state = FormSelectItem(
        label: "省份",
        value: employee?.province,
        validators: [FormRequiredValidator()],
        selectFieldController: ProvinceController());

    // 定义城市选择项
    FormSelectItem city = FormSelectItem(
        label: "城市",
        value: employee?.city,
        validators: [FormRequiredValidator()],
        selectFieldController: CityController());

    // 根据国家筛选省份
    state.filter(employee?.country);
    // 根据省份筛选城市
    city.filter(employee?.province);

    // 当省份变化时,更新城市选项
    state.addOnChangeListener((newStateSelected) {
      city.changeFilter(newStateSelected);
    });

    // 当国家变化时,更新省份选项
    country.addOnChangeListener((newCountrySelected) {
      state.changeFilter(newCountrySelected);
    });

    // 定义记住我复选框
    FormBoolItem rememberMe = FormBoolItem(label: "记住我");

    // 定义提交按钮
    btnSubmit = FormButton(
        label: "确定",
        onTap: (context) {
          if (validate()) {
            onSubmit(context, getEmployee());
          }
        });

    // 定义取消按钮
    btnCancel = FormButton(
        label: "取消",
        onTap: (context) {
          setEmployee(Employee(name: "", password: ""));
          onCancel(context);
        });

    // 添加字段到表单
    addField("name", name);
    addField("password", password);
    addField("birthday", birthday);
    addField("lastPost", lastPost);
    addField("country", country);
    addField("province", state);
    addField("city", city);
    addField("rememberMe", rememberMe);
  }

  // 获取员工信息
  Employee getEmployee() {
    Map<String, dynamic> empMap = buildObject();

    Employee employee = Employee(
        name: empMap["name"] ?? "", 
        password: empMap["password"] ?? "");
    employee.birthday = empMap["birthday"];
    employee.lastPost = empMap["lastPost"];
    employee.rememberMe = empMap["rememberMe"];
    employee.city = empMap["city"];
    employee.province = empMap["province"];
    employee.country = empMap["country"];
    return employee;
  }

  // 设置员工信息
  void setEmployee(Employee employee) {
    setItemValue("name", employee.name);
    setItemValue("password", employee.password);
    setItemValue("birthday", employee.birthday);
    setItemValue("lastPost", employee.lastPost);
    setItemValue("country", employee.country);
    setItemValue("province", employee.province);
    setItemValue("city", employee.city);
    setItemValue("rememberMe", employee.rememberMe);
  }

  // 获取输入项样式
  FormItemStyle getInputStyle() {
    return FormItemStyle(
        labelAlign: TextAlign.start,
        labelPosition: FieldLabelPosition.borderTop,
        labelSize: 6,
        labelStyle: const TextStyle(
            fontWeight: FontWeight.w400, color: Colors.black54, fontSize: 18),
        inputTextAlign: TextAlign.left,
        inputStyle: const TextStyle(
            fontWeight: FontWeight.w400, color: Colors.black87, fontSize: 18),
        errorInputStyle: const TextStyle(
            fontWeight: FontWeight.w400, color: Colors.red, fontSize: 18),
        fillColor: Colors.white);
  }

  // 获取密码输入项样式
  FormItemStyle getPasswordInputStyle() {
    return FormItemStyle(
        labelAlign: TextAlign.start,
        labelPosition: FieldLabelPosition.inside,
        labelSize: 6,
        labelStyle: const TextStyle(
            fontWeight: FontWeight.w400, color: Colors.black54, fontSize: 18),
        inputTextAlign: TextAlign.left,
        inputStyle: const TextStyle(
            fontWeight: FontWeight.w400, color: Colors.black87, fontSize: 18),
        errorInputStyle: const TextStyle(
            fontWeight: FontWeight.w400, color: Colors.red, fontSize: 18),
        fillColor: Colors.white,
        hideText: true);
  }
}
2. 使用 FormEmployee
FormEmployee form = FormEmployee(
    employee: Employee(
        name: "Simon",
        password: "",
        country: Country(2, "Brasil"),
        province: Province(4, "San Pablo", 2),
        city: City(9, "San Pablo 1", 4)),
    onSubmit: (context, Employee emp) {
      // 提交表单后的操作
      print("提交成功: ${emp.toJson()}");
    },
    onCancel: (context) {
      // 取消表单后的操作
      print("取消表单");
    });
3. 渲染表单
Widget getMyForm(BuildContext context) {
  return Center(
      child: form.draw(context)
  );  
}
4. 完整的 main.dart 示例
import 'package:example/employee_submitted.dart';
import 'package:example/example/form_employee.dart';
import 'package:example/example/model/city.dart';
import 'package:example/example/model/country.dart';
import 'package:example/example/model/employee.dart';
import 'package:example/example/model/province.dart';
import 'package:flutter/material.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: MyHomePage(title: '动态表单示例页面'),
    );
  }
}

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

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

class _MyHomePageState extends State<MyHomePage> {
  FormEmployee form = FormEmployee(
      employee: Employee(
          name: "Bernardo",
          password: "",
          country: Country(2, "Brasil"),
          province: Province(4, "San Pablo", 2),
          city: City(9, "San Pablo 1", 4)),
      onSubmit: (context, Employee emp) {
        Navigator.of(context).push(MaterialPageRoute(builder: (BuildContext context) {
          return EmployeeSubmitted(employee: emp);
        }));
      },
      onCancel: (context) {});

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: Text(widget.title),
      ),
      body: Center(child: form.draw(context)),
    );
  }
}

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

1 回复

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


当然,以下是一个关于如何使用 fiona_dynamic_form 插件来构建动态表单的示例代码。fiona_dynamic_form 是一个强大的 Flutter 插件,允许你根据 JSON 配置动态生成表单。

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

dependencies:
  flutter:
    sdk: flutter
  fiona_dynamic_form: ^最新版本号 # 请替换为实际的最新版本号

然后运行 flutter pub get 来获取依赖。

接下来,我们编写一个示例应用,展示如何使用 fiona_dynamic_form 插件。

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

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

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

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  final _formKey = GlobalKey<FormState>();

  // 示例表单配置 JSON
  String formJson = '''
  {
    "type": "form",
    "children": [
      {
        "type": "text",
        "name": "name",
        "label": "Name",
        "rules": [{"required": true, "message": "Please input your name", "trigger": "blur"}]
      },
      {
        "type": "email",
        "name": "email",
        "label": "Email",
        "rules": [{"type": "email", "required": true, "message": "Please input a valid email", "trigger": "blur"}]
      },
      {
        "type": "number",
        "name": "age",
        "label": "Age",
        "rules": [{"required": true, "message": "Please input your age", "trigger": "blur", "type": "number"}]
      },
      {
        "type": "checkbox",
        "name": "hobbies",
        "label": "Hobbies",
        "options": [
          {"label": "Reading", "value": "reading"},
          {"label": "Swimming", "value": "swimming"},
          {"label": "Running", "value": "running"}
        ],
        "rules": [{"required": true, "message": "Please select at least one hobby", "trigger": "change"}]
      },
      {
        "type": "button",
        "label": "Submit",
        "actionType": "submit"
      }
    ]
  }
  ''';

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Dynamic Form Demo'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: DynamicForm(
          key: _formKey,
          formJson: formJson,
          onFinish: (values) {
            // 提交表单后的处理逻辑
            print('Form Values: $values');
            ScaffoldMessenger.of(context).showSnackBar(
              SnackBar(content: Text('Form Submitted')),
            );
          },
        ),
      ),
    );
  }
}

在这个示例中,我们定义了一个 JSON 格式的表单配置,其中包括了文本输入、电子邮件输入、数字输入、复选框以及一个提交按钮。

  1. 文本输入 (type: "text"): 用于输入名称。
  2. 电子邮件输入 (type: "email"): 用于输入电子邮件地址。
  3. 数字输入 (type: "number"): 用于输入年龄。
  4. 复选框 (type: "checkbox"): 用于选择兴趣爱好。
  5. 提交按钮 (type: "button"): 提交表单。

DynamicForm 组件接收 formJson 作为表单配置,并根据该配置动态生成表单。当用户点击提交按钮时,onFinish 回调会被触发,并传递表单值。

你可以根据需要修改 formJson 来定义不同的表单结构和验证规则。

希望这个示例能帮助你理解如何使用 fiona_dynamic_form 插件来构建动态表单。如果有任何进一步的问题,请随时提问!

回到顶部