Flutter自动生成表单插件json_gen_form的使用
Flutter自动生成表单插件json_gen_form的使用
JSON_GEN_FORM
使用JSON生成Flutter表单,支持多种内置表单控件、验证、自定义布局、自定义样式以及无限嵌套的表单分组。
特性
- 使用JSON渲染表单
- 表单验证
- 自定义表单样式
- 自定义布局(行、列)
- 无限表单分组和嵌套
- 可以通过方法修改整个表单值或单独的表单控件值
- 支持的表单控件:
- 文本框
- 密码框
- 多行文本框
- 数字输入框
- 单选按钮
- 复选框
- 下拉选择框
- 开关
- 多媒体上传
- 日期选择器
- 时间选择器
- 日期时间选择器
使用
import 'package:flutter/material.dart';
import 'package:json_gen_form/json_gen_form.dart';
void main() {
runApp(const MainApp());
}
class MainApp extends StatefulWidget {
const MainApp({super.key});
@override
State<MainApp> createState() => _MainAppState();
}
class _MainAppState extends State<MainApp> {
final GlobalKey _key = GlobalKey<JsonGenFormState>();
final List<dynamic> _data = [
{
"type": "group",
"label": "分组1",
"field": "group1",
"children": [
{
"type": "row",
"gutter": 10,
"children": [
{
"type": "col",
"child": {"type": "text", "field": "name", "label": "组名1"}
},
{
"type": "col",
"child": {"type": "number", "field": "num", "label": "人数"}
}
]
},
{"type": "text", "field": "manage", "label": "管理员"}
]
},
{
"type": "text",
"field": "name",
"label": "姓名",
"value": "隔壁老王",
"readonly": true,
"placeholder": "请输入姓名",
"rules": [
{"required": true, "message": "请输入姓名"}
]
},
{
"type": "password",
"field": "password",
"label": "密码",
"value": null,
"placeholder": "请输入密码",
"rules": [
{"required": true, "message": "请输入密码"},
{
"pattern": "^[a-zA-Z0-9_-]{6,16}$",
"message": "密码必须为6-16位字母、数字、下划线、减号"
}
]
},
{
"type": "textarea",
"field": "remark",
"label": "自我介绍",
"value": null,
"placeholder": "请简单介绍一下你自己",
"rules": []
},
{
"type": "number",
"field": "age",
"label": "年龄",
"value": null,
"placeholder": "请输入年龄",
"rules": [
{"required": true, "message": "请输入年龄"},
{"min": 18, "message": "年龄必须大于18岁"}
]
},
{
"type": "select",
"field": "province",
"label": "省份",
"value": 1,
"placeholder": "请选择省份",
"options": [
{"label": "山西", "value": 1},
{"label": "陕西", "value": 2},
{"label": "山东", "value": 3}
]
},
{
"type": "cascade",
"field": "city",
"label": "城市",
"value": null,
"placeholder": "请选择城市",
"options": [
{
"label": "山西",
"value": 1,
"children": [
{
"label": "太原",
"value": 11,
"children": [
{"label": "小店区", "value": 111},
{"label": "迎泽区", "value": 112}
]
},
{"label": "吕梁", "value": 12},
{"label": "大同", "value": 13}
]
},
{
"label": "陕西",
"value": 2,
"children": [
{"label": "西安", "value": 21},
{"label": "咸阳", "value": 22}
]
}
]
},
{
"type": "date",
"field": "birthday",
"label": "生日",
"value": null,
"placeholder": "请选择生日"
},
{
"type": "radio",
"field": "sex",
"label": "性别",
"value": null,
"options": [
{"label": "男", "value": 1},
{"label": "女", "value": 2},
{"label": "保密", "value": 0}
]
},
{
"type": "checkbox",
"field": "hobby",
"label": "爱好",
"value": [],
// "direction": "vertical",
"options": [
{"label": "篮球", "value": "basketball"},
{"label": "足球", "value": "football"},
{"label": "羽毛球", "value": "badminton"}
],
"rules": [
{"required": true, "message": "请选择爱好"}
]
},
{
"type": "switch",
"field": "agree",
"label": "同意协议",
"value": null,
"rules": [
{"required": true, "message": "请同意协议"}
]
},
{
"type": "media",
"field": "media",
"label": "上传照片视频",
"value": null,
"rules": null,
"multiple": true
}
];
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
brightness: Brightness.light,
useMaterial3: true,
),
home: Scaffold(
appBar: AppBar(
title: const Text('json gen form'),
),
body: SafeArea(
child: SingleChildScrollView(
physics: const BouncingScrollPhysics(),
padding: const EdgeInsets.symmetric(
horizontal: 20.0,
vertical: 20.0,
),
child: Column(
children: [
JsonGenForm(
key: _key,
config: _data,
decoration: JsonGenFormDecoration(
// groupLabelWrap: (Widget child, dynamic data) {
// return Container(
// margin: const EdgeInsets.only(bottom: 5),
// child: child,
// );
// },
controlLabelWrap: (Widget child, dynamic data) {
return Container(
margin: const EdgeInsets.only(bottom: 5),
child: child,
);
},
controlWrap: (Widget child, dynamic data) {
return Container(
margin: const EdgeInsets.only(bottom: 10),
child: child,
);
},
),
),
ElevatedButton(
onPressed: () async {
final formState = _key.currentState as JsonGenFormState;
try {
final data = await formState.validate();
debugPrint('提交成功 $data');
} catch (e) {
debugPrint('Validation error: $e');
}
},
child: const Text('提交'),
),
],
),
),
),
),
);
}
}
通用参数
除了group
, row
, 和 col
,所有类型都有以下通用参数。所有类型都有extra
。
字段 | 描述 | 类型 | 默认值 | 必填 |
---|---|---|---|---|
type | 类型 | String | ‘’ | 是 |
field | 字段名称 | String | ‘’ | 是 |
label | 标签 | String | - | - |
hiddenLabel | 隐藏标签 | bool | false | - |
value | 默认值 | dynamic | - | - |
disabled | 禁用 | bool | false | - |
readonly | 只读 | bool | false | - |
rules | 验证规则 | List | [] | - |
extra | 额外参数 | dynamic | - | - |
表单类型
分组 (group)
字段 | 描述 | 类型 | 默认值 | 必填 |
---|---|---|---|---|
type | 类型 | String | ‘group’ | 是 |
field | 字段名称 | String | ‘’ | - |
label | 标签 | String | ‘’ | - |
hiddenLabel | 隐藏标签 | bool | ‘’ | - |
children | 子表单 | List | [] | - |
文本框 (text)
字段 | 描述 | 类型 | 默认值 | 必填 |
---|---|---|---|---|
type | 类型 | String | ‘text’ | 是 |
placeholder | 占位符 | String | - | - |
通用参数 | - | - | - | - |
密码框 (password)
字段 | 描述 | 类型 | 默认值 | 必填 |
---|---|---|---|---|
type | 类型 | String | ‘password’ | 是 |
placeholder | 占位符 | String | - | - |
通用参数 | - | - | - | - |
多行文本框 (textarea)
字段 | 描述 | 类型 | 默认值 | 必填 |
---|---|---|---|---|
type | 类型 | String | ‘textarea’ | 是 |
placeholder | 占位符 | String | - | - |
通用参数 | - | - | - | - |
数字输入框 (number)
字段 | 描述 | 类型 | 默认值 | 必填 |
---|---|---|---|---|
type | 类型 | String | ‘number’ | 是 |
placeholder | 占位符 | String | - | - |
通用参数 | - | - | - | - |
单选按钮 (radio)
字段 | 描述 | 类型 | 默认值 | 必填 |
---|---|---|---|---|
type | 类型 | String | ‘radio’ | 是 |
options | 选项 | List | [] | - |
direction | 选项方向 | String | ‘horizontal’ | - |
itemHorizontalSpace | 项目水平间距 | double | 16 | - |
itemVerticalSpace | 项目垂直间距 | double | 8 | - |
通用参数 | - | - | - | - |
复选框 (checkbox)
字段 | 描述 | 类型 | 默认值 | 必填 |
---|---|---|---|---|
type | 类型 | String | ‘checkbox’ | 是 |
options | 选项 | List | [] | - |
direction | 选项方向 | String | ‘horizontal’ | - |
itemHorizontalSpace | 项目水平间距 | double | 16 | - |
itemVerticalSpace | 项目垂直间距 | double | 8 | - |
通用参数 | - | - | - | - |
下拉选择框 (select)
字段 | 描述 | 类型 | 默认值 | 必填 |
---|---|---|---|---|
type | 类型 | String | ‘select’ | 是 |
options | 选项 | List | [] | - |
multiple | 多选 | bool | false | - |
通用参数 | - | - | - | - |
开关 (switch)
字段 | 描述 | 类型 | 默认值 | 必填 |
---|---|---|---|---|
type | 类型 | String | ‘switch’ | 是 |
通用参数 | - | - | - | - |
多媒体上传 (media)
字段 | 描述 | 类型 | 默认值 | 必填 |
---|---|---|---|---|
type | 类型 | String | ‘media’ | 是 |
mediaType | 媒体类型 (media, image, video) | String | ‘media’ | - |
multiple | 多次上传 | bool | false | - |
通用参数 | - | - | - | - |
iOS配置 (info.plist)
<key>NSCameraUsageDescription</key>
<string>需要相机拍照或扫描二维码</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>需要访问相册选择照片或视频</string>
<key>NSMicrophoneUsageDescription</key>
<string>需要麦克风录制视频</string>
Android配置 (AndroidManifest.xml)
<uses-permission android:name="android.permission.CAMERA" />
更多关于Flutter自动生成表单插件json_gen_form的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter自动生成表单插件json_gen_form的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,下面是一个关于如何在Flutter项目中使用json_gen_form
插件自动生成表单的示例代码。这个插件允许你通过JSON配置来生成表单,非常适合需要动态生成表单的场景。
首先,确保你已经在pubspec.yaml
文件中添加了json_gen_form
依赖:
dependencies:
flutter:
sdk: flutter
json_gen_form: ^最新版本号 # 请替换为实际的最新版本号
然后,运行flutter pub get
来安装依赖。
接下来,创建一个JSON文件(例如form_config.json
),用于定义表单的结构:
[
{
"type": "TextFormField",
"key": "name",
"label": "Name",
"hintText": "Enter your name",
"validator": {"required": true, "errorMessage": "Name is required"}
},
{
"type": "DropdownButtonFormField",
"key": "gender",
"label": "Gender",
"hintText": "Select your gender",
"validator": {"required": true, "errorMessage": "Gender is required"},
"options": [
{"value": "male", "label": "Male"},
{"value": "female", "label": "Female"}
]
},
{
"type": "CheckboxListTile",
"key": "interests",
"label": "Interests",
"title": "Select your interests",
"options": [
{"value": "sports", "label": "Sports"},
{"value": "music", "label": "Music"},
{"value": "reading", "label": "Reading"}
]
},
{
"type": "ElevatedButton",
"key": "submit",
"label": "Submit",
"onPressed": "submitForm"
}
]
注意:json_gen_form
插件的具体用法可能依赖于其内部实现和版本,上面的JSON配置是一个假设性的示例,实际使用时需要根据插件的文档进行调整。
接下来,在你的Flutter项目中编写代码来加载这个JSON配置并生成表单:
import 'package:flutter/material.dart';
import 'package:json_gen_form/json_gen_form.dart'; // 假设这是插件的导入路径
import 'dart:convert';
import 'package:flutter/services.dart' show rootBundle;
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('JSON Generated Form'),
),
body: FutureBuilder<String>(
future: loadAsset(),
builder: (BuildContext context, AsyncSnapshot<String> snapshot) {
if (snapshot.hasError) {
return Center(child: Text('Failed to load asset: ${snapshot.error}'));
} else if (snapshot.connectionState == ConnectionState.done) {
final List formConfig = jsonDecode(snapshot.data!);
return JsonGenForm(
formConfig: formConfig,
onFormSubmit: (Map<String, dynamic> formData) {
// 处理表单提交
print('Form Data: $formData');
},
);
} else {
return Center(child: CircularProgressIndicator());
}
},
),
),
);
}
Future<String> loadAsset() async {
return await rootBundle.loadString('assets/form_config.json');
}
}
在这个示例中,FutureBuilder
用于异步加载JSON配置文件。一旦文件加载完成,JsonGenForm
组件将使用加载的配置来生成表单。onFormSubmit
回调用于处理表单提交事件。
请注意,由于json_gen_form
插件的具体实现可能有所不同,上面的代码可能需要根据插件的实际API进行调整。务必参考插件的官方文档和示例代码来获取最准确的信息。
此外,确保在pubspec.yaml
文件的flutter
部分下添加对form_config.json
文件的引用:
flutter:
assets:
- assets/form_config.json
这样,你就可以在Flutter项目中通过JSON配置动态生成表单了。