Flutter表单生成插件form_gen的使用
Flutter表单生成插件form_gen的使用
特性
form_gen 是一个可以根据模型生成表单的插件。该模型通过 [@FormBuilder](/user/FormBuilder)
装饰,并且每个屏幕项目都通过 @FieldXXXX
字段装饰,然后从终端运行 build_runner
来生成表单。生成的表单和用于序列化与反序列化的 JSON 操作会被放置在一个扩展名为 g.dart
的文件中。
开始使用
在开始之前,请确保删除示例中的 example/lib/profile.g.dart
文件。
flutter pub run build_runner build
此步骤会在 example/lib/profile.g.dart
中生成 Profile
屏幕的 ProfileForm()
小部件代码。
使用Form Gen
Form Gen 插件通常与以下包一起使用:
这些 Json 包的作用是(引用):
“为类生成到/从 JSON 的代码,使用 JsonSerializable
进行注解。你可以通过 JsonSerializable
提供参数来自定义生成的代码。你也可以通过注解字段并提供自定义参数来单独定制字段。详见下表中的注解值。”
要生成一个包含 JSON 文件内容的 Dart 字段,可以使用 JsonLiteral
注解。
导入包
import 'package:json_annotation/json_annotation.dart';
import 'package:form_gen/form_gen.dart';
装饰模型类
[@JsonSerializable](/user/JsonSerializable)()
[@FormBuilder](/user/FormBuilder)(
platform: TargetPlatform.iOS,
)
class Profile {
// 装饰每个字段
[@FieldText](/user/FieldText)(
label: 'First name',
hint: 'Enter your first name',
enabled: true,
inputDecoration: {'label': 'First name', 'hint': 'Enter your first name', 'helper': 'We need your first name', 'error': 'Please enter your first name'},
sequence: 0.0,
validators: [
{
FieldValidator.required: {'message': '"Please enter your first name"'}
},
],
)
final String firstName;
// 其他字段...
}
支持的字段类型
以下表单字段类型被支持:
- CheckBox
- ChoiceChip
- Class - 将字段分组以支持子字段
- DateRangePicker
- DateTimePicker
- DropdownHideUnderline
- Dropdown
- FilterChip
- Radio
- Slider
- Switch
- TextArea
- Text
每个字段有许多属性(通常是与对应的 Flutter 小部件相同的属性)。有关更多信息,请参阅 API 文档。
完整示例代码
以下是一个完整的示例代码,展示了如何使用 form_gen
插件。
示例代码:main.dart
// ignore_for_file: prefer_const_constructors
import 'package:flutter/material.dart';
import 'profile.dart';
import 'package:flutter/services.dart';
void main() {
runApp(MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter Form Generator',
theme: ThemeData(
primarySwatch: Colors.amber,
),
home: const Home(),
));
}
class Home extends StatefulWidget {
const Home({Key? key}) : super(key: key);
@override
State<Home> createState() => _HomeState();
}
class _HomeState extends State<Home> {
// 初始化数据列表
List<Profile> _profiles = [
Profile(
firstName: 'Rajesh',
lastName: 'Kumar',
profileType: ProfileType.personal,
grade: Grades.executive,
birthdate: DateTime.parse('2000-01-01'),
email: 'rajest@personal.com',
phone: '1234567890',
journeyDates: '2000-01-01,2000-01-01',
description: 'I am a programmer',
salary: 40000,
salaryRange: '40000,80000',
address: Address(
street: '123 Main St',
city: 'Bangalore',
state: 'Karnataka',
postcode: 'X570037',
),
website: 'https://rajeshkumar.com',
avatar: 'https://i.pravatar.cc/300',
)
];
@override
void initState() {
SystemChrome.setEnabledSystemUIMode(SystemUiMode.immersiveSticky);
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Form Gen Example'),
),
body: SizedBox(
height: 900,
child: Column(
children: [
Expanded(
child: ListView.builder(
itemCount: _profiles.length,
itemBuilder: (context, index) {
final profile = _profiles[index];
return Padding(
padding: const EdgeInsets.all(0.0),
child: ListTile(
leading: FittedBox(
fit: BoxFit.contain,
child: CircleAvatar(
backgroundImage: NetworkImage(profile.avatar),
),
),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
),
focusColor: Theme.of(context).primaryColor,
tileColor: Theme.of(context).backgroundColor.withOpacity(0.3),
title: Text(profile.firstName + ' ' + profile.lastName),
subtitle: Text(profile.email),
trailing: const Icon(Icons.keyboard_arrow_right),
onTap: () async {
final response = await Navigator.push(
context,
MaterialPageRoute(
builder: (context) => Padding(
padding: const EdgeInsets.all(24.0),
child: ProfileForm(
model: profile,
showAppBar: false,
),
),
),
);
if (response is Profile) {
setState(() {
_profiles[index] = response;
});
}
},
),
);
},
),
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: () async {
final response = await Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const ProfileForm(),
),
);
if (response is Profile) {
setState(() {
_profiles.add(response);
});
}
},
child: const Icon(Icons.add),
),
);
}
}
示例代码:profile.dart
import 'package:json_annotation/json_annotation.dart';
import 'package:form_gen/form_gen.dart';
part 'profile.g.dart';
[@JsonSerializable](/user/JsonSerializable)()
[@FormBuilder](/user/FormBuilder)(
platform: TargetPlatform.iOS,
)
class Profile {
[@FieldText](/user/FieldText)(
label: 'First name',
hint: 'Enter your first name',
enabled: true,
inputDecoration: {'label': 'First name', 'hint': 'Enter your first name', 'helper': 'We need your first name', 'error': 'Please enter your first name'},
sequence: 0.0,
validators: [
{
FieldValidator.required: {'message': '"Please enter your first name"'}
},
],
)
final String firstName;
[@FieldText](/user/FieldText)(
label: 'Last name',
hint: 'Enter your last name',
enabled: true,
inputDecoration: {'label': 'Last name', 'hint': 'Enter your last name', 'helper': 'We need your last name', 'error': 'Please enter your last name'},
sequence: 1.0,
validators: [
{
FieldValidator.required: {'message': '"Please enter your last name"'}
},
],
)
final String lastName;
[@FieldEnum](/user/FieldEnum)(
label: 'Profile Type',
hint: 'Select your profile type',
enabled: true,
sequence: 2.0,
enumValues: ProfileType.values,
validators: [
{
FieldValidator.required: {'message': '"Please select your profile type"'}
},
],
)
final ProfileType profileType;
[@FieldEnum](/user/FieldEnum)(
label: 'Grade',
hint: 'Select your grade',
enabled: true,
sequence: 3.0,
enumValues: Grades.values,
validators: [
{
FieldValidator.required: {'message': '"Please select your grade"'}
},
],
)
final Grades grade;
[@FieldDate](/user/FieldDate)(
label: 'Birthdate',
hint: 'Enter your birthdate',
enabled: true,
sequence: 4.0,
validators: [
{
FieldValidator.required: {'message': '"Please enter your birthdate"'}
},
],
)
final DateTime birthdate;
[@FieldText](/user/FieldText)(
label: 'Email',
hint: 'Enter your email',
enabled: true,
inputDecoration: {'label': 'Email', 'hint': 'Enter your email', 'helper': 'We need your email', 'error': 'Please enter a valid email'},
sequence: 5.0,
validators: [
{
FieldValidator.required: {'message': '"Please enter your email"'},
FieldValidator.email: {'message': '"Please enter a valid email"'}
},
],
)
final String email;
[@FieldText](/user/FieldText)(
label: 'Phone',
hint: 'Enter your phone',
enabled: true,
inputDecoration: {'label': 'Phone', 'hint': 'Enter your phone', 'helper': 'We need your phone', 'error': 'Please enter your phone'},
sequence: 6.0,
validators: [
{
FieldValidator.required: {'message': '"Please enter your phone"'}
},
],
)
final String phone;
[@FieldText](/user/FieldText)(
label: 'Journey Dates',
hint: 'Enter your journey dates',
enabled: true,
inputDecoration: {'label': 'Journey Dates', 'hint': 'Enter your journey dates', 'helper': 'We need your journey dates', 'error': 'Please enter your journey dates'},
sequence: 7.0,
validators: [
{
FieldValidator.required: {'message': '"Please enter your journey dates"'}
},
],
)
final String journeyDates;
[@FieldTextArea](/user/FieldTextArea)(
label: 'Description',
hint: 'Enter your description',
enabled: true,
inputDecoration: {'label': 'Description', 'hint': 'Enter your description', 'helper': 'We need your description', 'error': 'Please enter your description'},
sequence: 8.0,
)
final String description;
[@FieldNumber](/user/FieldNumber)(
label: 'Salary',
hint: 'Enter your salary',
enabled: true,
inputDecoration: {'label': 'Salary', 'hint': 'Enter your salary', 'helper': 'We need your salary', 'error': 'Please enter your salary'},
sequence: 9.0,
validators: [
{
FieldValidator.required: {'message': '"Please enter your salary"'}
},
],
)
final double salary;
[@FieldRange](/user/FieldRange)(
label: 'Salary Range',
hint: 'Enter your salary range',
enabled: true,
inputDecoration: {'label': 'Salary Range', 'hint': 'Enter your salary range', 'helper': 'We need your salary range', 'error': 'Please enter your salary range'},
sequence: 10.0,
min: 40000,
max: 80000,
validators: [
{
FieldValidator.required: {'message': '"Please enter your salary range"'}
},
],
)
final String salaryRange;
[@FieldObject](/user/FieldObject)(
label: 'Address',
hint: 'Enter your address',
enabled: true,
inputDecoration: {'label': 'Address', 'hint': 'Enter your address', 'helper': 'We need your address', 'error': 'Please enter your address'},
sequence: 11.0,
)
final Address address;
[@FieldText](/user/FieldText)(
label: 'Website',
hint: 'Enter your website',
enabled: true,
inputDecoration: {'label': 'Website', 'hint': 'Enter your website', 'helper': 'We need your website', 'error': 'Please enter your website'},
sequence: 12.0,
)
final String website;
[@FieldImage](/user/FieldImage)(
label: 'Avatar',
hint: 'Enter your avatar URL',
enabled: true,
inputDecoration: {'label': 'Avatar', 'hint': 'Enter your avatar URL', 'helper': 'We need your avatar URL', 'error': 'Please enter your avatar URL'},
sequence: 13.0,
)
final String avatar;
Profile({
required this.firstName,
required this.lastName,
required this.profileType,
required this.grade,
required this.birthdate,
required this.email,
required this.phone,
required this.journeyDates,
required this.description,
required this.salary,
required this.salaryRange,
required this.address,
required this.website,
required this.avatar,
});
factory Profile.fromJson(Map<String, dynamic> json) => _$ProfileFromJson(json);
Map<String, dynamic> toJson() => _$ProfileToJson(this);
}
[@JsonSerializable](/user/JsonSerializable)()
class Address {
final String street;
final String city;
final String state;
final String postcode;
Address({
required this.street,
required this.city,
required this.state,
required this.postcode,
});
factory Address.fromJson(Map<String, dynamic> json) => _$AddressFromJson(json);
Map<String, dynamic> toJson() => _$AddressToJson(this);
}
enum ProfileType { personal, professional }
enum Grades { executive, senior, junior }
更多关于Flutter表单生成插件form_gen的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter表单生成插件form_gen的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
form_gen
是一个用于 Flutter 的插件,它可以帮助开发者快速生成表单。通过 form_gen
,你可以根据 JSON 配置文件自动生成表单,从而减少手动编写表单代码的工作量。以下是如何使用 form_gen
的基本步骤:
1. 添加依赖
首先,你需要在 pubspec.yaml
文件中添加 form_gen
依赖:
dependencies:
flutter:
sdk: flutter
form_gen: ^1.0.0 # 请使用最新版本
然后运行 flutter pub get
来安装依赖。
2. 创建 JSON 配置文件
form_gen
通过 JSON 配置文件来定义表单的结构。你可以创建一个 JSON 文件来定义表单的字段、类型、验证规则等。
例如,创建一个 form_config.json
文件:
{
"fields": [
{
"type": "text",
"label": "Username",
"name": "username",
"placeholder": "Enter your username",
"validations": [
{
"type": "required",
"message": "Username is required"
}
]
},
{
"type": "password",
"label": "Password",
"name": "password",
"placeholder": "Enter your password",
"validations": [
{
"type": "required",
"message": "Password is required"
},
{
"type": "minLength",
"value": 6,
"message": "Password must be at least 6 characters"
}
]
},
{
"type": "email",
"label": "Email",
"name": "email",
"placeholder": "Enter your email",
"validations": [
{
"type": "required",
"message": "Email is required"
},
{
"type": "email",
"message": "Please enter a valid email"
}
]
}
]
}
3. 使用 form_gen
生成表单
在你的 Flutter 项目中,你可以使用 form_gen
来根据 JSON 配置文件生成表单。
import 'package:flutter/material.dart';
import 'package:form_gen/form_gen.dart';
class MyForm extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Form Example'),
),
body: FormGen.fromJson('assets/form_config.json'),
);
}
}
void main() {
runApp(MaterialApp(
home: MyForm(),
));
}
4. 加载 JSON 文件
确保你的 JSON 文件在 assets
目录下,并在 pubspec.yaml
中声明:
flutter:
assets:
- assets/form_config.json
5. 处理表单提交
form_gen
生成的表单通常会返回一个 Form
对象,你可以通过 Form
的 onSaved
或 onChanged
回调来处理表单数据。
class MyForm extends StatelessWidget {
final _formKey = GlobalKey<FormState>();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Form Example'),
),
body: Form(
key: _formKey,
child: FormGen.fromJson('assets/form_config.json'),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
if (_formKey.currentState!.validate()) {
_formKey.currentState!.save();
// 处理表单数据
}
},
child: Icon(Icons.save),
),
);
}
}
6. 自定义表单字段
form_gen
支持多种类型的表单字段,如文本、密码、邮箱、日期等。你还可以通过自定义字段类型来扩展表单功能。
7. 验证规则
form_gen
支持多种验证规则,如 required
、minLength
、maxLength
、email
等。你可以在 JSON 配置文件中为每个字段定义验证规则。
8. 样式和布局
你可以通过自定义样式和布局来调整表单的外观。form_gen
提供了多种选项来定制表单的样式。
9. 处理表单数据
在表单提交时,你可以通过 Form
的 onSaved
回调来获取表单数据,并进行进一步处理。
onPressed: () {
if (_formKey.currentState!.validate()) {
_formKey.currentState!.save();
// 获取表单数据
final formData = _formKey.currentState!.value;
print(formData);
}
}