Flutter表单构建插件fl_form的使用
Flutter表单构建插件fl_form的使用
特性

![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
此包为您的应用程序提供了一些数据类型的表单字段,它可以与您应用中的表单一起工作。
- 文本输入
- 头像
- 日期、时间、持续时间
- 单项选择器
- 多项选择器
- 布尔值
- 单选按钮
- 复选框组
使用
需要主题扩展
表单字段要求应用程序使用主题扩展: FlFormFieldTheme
配置
MaterialApp(
title: 'Flutter Demo',
theme: ThemeData.dark(
useMaterial3: true,
).copyWith(extensions: [
FlFormFieldTheme.dark(context),
]),
home: const MainExample(),
);
FlFormFieldTheme
...
final TextStyle labelStyle;
final InputDecorationTheme inputDecorationTheme;
final TextStyle style;
final TextStyle errorStyle;
final TextStyle placeHolderStyle;
FlFormFieldTheme({
required this.labelStyle,
required this.inputDecorationTheme,
required this.style,
required this.errorStyle,
required this.placeHolderStyle,
});
1. FlTextFormField

示例:简单文本
FlTextFormField(
label: 'Email',
isRequired: true,
autovalidateMode: AutovalidateMode.always,
validator: (value) {
return 'Email invalid';
},
placeholderText: 'Type your email',
),
示例:密码文本
FlTextFormField(
prefixIcon: const Icon(Icons.lock),
label: 'Password',
placeholderText: '* * * * * *',
isRequired: true,
isPassword: true,
),
示例:区域文本
FlTextFormField(
maxLines: 4,
label: 'Description',
autovalidateMode: AutovalidateMode.always,
placeholderText: 'Type your description',
validator: (value) {
return 'Description invalid';
},
),
FlDateFormField

FlDateFormField(
autovalidateMode: AutovalidateMode.always,
prefixIcon: const Icon(Icons.date_range),
firstDate: DateTime.now(),
lastDate: DateTime.now().add(const Duration(days: 100)),
label: 'Date of birth',
placeholderText: 'dd/MM/yyyy',
validator: (value) {
return 'Date invalid';
},
),
FlTimeFormField
FlTimeFormField(
label: 'Time Start',
placeholderText: 'HH:MM',
autovalidateMode: AutovalidateMode.always,
validator: (value) {
return 'Time invalid';
},
prefixIcon: Icon(Icons.alarm),
),
FlDateAndTimeFormField

FlDateAndTimeFormField(
firstDate: DateTime.now(),
lastDate: DateTime.now().add(const Duration(days: 100)),
label: 'Date of birth',
placeholderText: 'dd/MM/yyyy',
autovalidateMode: AutovalidateMode.always,
validator: (value) => 'Date invalid',
),
FlDurationFormField
FlDurationFormField(
prefixIcon: Icon(Icons.date_range),
label: 'Select Duration',
placeholderText: 'hh : mm',
),
AvatarFormFieldPage
1. 默认头像表单字段
FlAvatarFormField(
radius: 64,
autovalidateMode: AutovalidateMode.always,
validator: (value) {
if (value == null) {
return 'Need update your avatar';
}
},
),
2. 自定义头像表单字段
Center(
child: FlRawAvatarFormField(
builder: (
{required context, data, required didChange, error}) {
if (data == null) {
return GestureDetector(
onTap: () {
FlRawAvatarFormField.pickFile().then((value) {
if (value != null) {
didChange(value);
}
});
},
child: Container(
height: 80,
width: 80,
decoration: BoxDecoration(
color: Colors.grey,
borderRadius: BorderRadius.circular(12),
),
),
);
} else {
if (data.file != null) {
return Container(
height: 80,
width: 80,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(12),
image: DecorationImage(
fit: BoxFit.cover,
image: FileImage(data.file!))),
);
} else {
return Container(
height: 80,
width: 80,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(12),
image: DecorationImage(
fit: BoxFit.cover,
image: NetworkImage(data.link!))),
);
}
}
},
),
),
Bool Value FormField

1. FlBoolFormField
FlBoolFormField(
spacing: 16,
title: 'Select All',
)
2. FlRawBoolFormField
FlRawBoolFormField(
title: 'Select All',
rawBuilder: (context, data, didChange) {
return Container(
padding: const EdgeInsets.symmetric(vertical: 12),
child: Row(
children: [
Checkbox(
value: data ?? false,
onChanged: (value) {
didChange(value);
},
),
const Expanded(
child: Text('Select All'),
)
],
),
);
},
),
Single Item Picker Form Field

SingleItemPickerFormField<SimpleData>(
label: 'Select Item customize',
placeholderText: 'Select Item',
itemListBuilder: (context, data, isSelected) {
return Container(
padding: const EdgeInsets.symmetric(
vertical: 12,
horizontal: 16,
),
child: Row(
children: [
const CircleAvatar(
radius: 24,
),
const SizedBox(
width: 12,
),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
data.title,
style: Theme.of(context).textTheme.bodyMedium,
),
const SizedBox(
height: 2,
),
Text(
data.subTitle,
style: Theme.of(context).textTheme.labelMedium,
),
],
)),
if (isSelected) const Icon(Icons.done)
],
),
);
},
contentSelectedBuilder: (data, context) => Container(
child: Row(
children: [
const CircleAvatar(
radius: 16,
),
const SizedBox(
width: 12,
),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
data.title,
style: Theme.of(context).textTheme.bodyMedium,
),
const SizedBox(
height: 2,
),
Text(
data.subTitle,
style: Theme.of(context).textTheme.labelMedium,
),
],
))
],
),
),
options: [
SimpleData(title: 'Title 1', subTitle: 'Sub title 1'),
SimpleData(title: 'Title 2', subTitle: 'Sub title 2'),
SimpleData(title: 'Title 3', subTitle: 'Sub title 3'),
SimpleData(title: 'Title 4', subTitle: 'Sub title 4'),
SimpleData(title: 'Title 5', subTitle: 'Sub title 5'),
SimpleData(title: 'Title 6', subTitle: 'Sub title 6'),
SimpleData(title: 'Title 7', subTitle: 'Sub title 7'),
SimpleData(title: 'Title 8', subTitle: 'Sub title 8'),
],
)
Multiple Item Picker Form Field

MultipleItemPickerFormField<SimpleData>(
label: 'Select Items customize',
placeholderText: 'Select Items',
autovalidateMode: AutovalidateMode.always,
validator: (value) {
return 'Data Invalid';
},
itemListBuilder: (context, data, isSelected) {
return Container(
padding: const EdgeInsets.symmetric(
vertical: 12,
horizontal: 16,
),
child: Row(
children: [
const CircleAvatar(
radius: 24,
),
const SizedBox(
width: 12,
),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
data.title,
style: Theme.of(context).textTheme.bodyMedium,
),
const SizedBox(
height: 2,
),
Text(
data.subTitle,
style: Theme.of(context).textTheme.labelMedium,
),
],
)),
if (isSelected) const Icon(Icons.done)
],
),
);
},
contentSelectedBuilder: (data, context) => Container(
child: Wrap(
spacing: 8,
children: [
...data
?.map((e) => Chip(
label: Text(e.title),
))
.toList() ??
[]
],
),
),
options: [
SimpleData(title: 'Title 1', subTitle: 'Sub title 1'),
SimpleData(title: 'Title 2', subTitle: 'Sub title 2'),
SimpleData(title: 'Title 3', subTitle: 'Sub title 3'),
SimpleData(title: 'Title 4', subTitle: 'Sub title 4'),
SimpleData(title: 'Title 5', subTitle: 'Sub title 5'),
SimpleData(title: 'Title 6', subTitle: 'Sub title 6'),
SimpleData(title: 'Title 7', subTitle: 'Sub title 7'),
SimpleData(title: 'Title 8', subTitle: 'Sub title 8'),
],
)
Radio Button Group FormField

FlRadioButtonFormField(
isRequired: true,
autovalidateMode: AutovalidateMode.always,
validator: (value) {
if (value == null) return 'Data invalid';
return null;
},
label: 'Select Item',
options: const [
'Option 1',
'Option 2',
'Option 3',
],
)
Checbox Group FormField

FlCheckboxGroupFormField(
isRequired: true,
autovalidateMode: AutovalidateMode.always,
validator: (value) {
if (value == null || value.isEmpty) return 'Data invalid';
return null;
},
label: 'Select Item',
options: const [
'Item 1',
'Item 2',
'Item 3',
'Item 4',
'Item 5',
'Item 6',
],
)
更多关于Flutter表单构建插件fl_form的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
1 回复
更多关于Flutter表单构建插件fl_form的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
在Flutter中,fl_form
是一个用于构建和管理表单的插件,它提供了丰富的功能和灵活的API来简化表单开发。以下是一个使用 fl_form
构建简单表单的代码示例,展示了如何创建表单、添加字段、以及处理表单提交。
首先,确保你已经在 pubspec.yaml
文件中添加了 fl_form
依赖:
dependencies:
flutter:
sdk: flutter
fl_form: ^最新版本号 # 请替换为最新的版本号
然后,运行 flutter pub get
来获取依赖。
接下来,创建一个简单的 Flutter 应用,并使用 fl_form
来构建表单。以下是一个完整的示例代码:
import 'package:flutter/material.dart';
import 'package:fl_form/fl_form.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter 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>();
late FlFormController _formController;
@override
void initState() {
super.initState();
_formController = FlFormController(
fields: [
FlFormField(
name: 'name',
title: 'Name',
validators: [FlValidators.required()],
widget: TextFormField(
decoration: InputDecoration(border: OutlineInputBorder()),
),
),
FlFormField(
name: 'email',
title: 'Email',
validators: [
FlValidators.required(),
FlValidators.email(),
],
widget: TextFormField(
decoration: InputDecoration(border: OutlineInputBorder()),
keyboardType: TextInputType.emailAddress,
),
),
FlFormField(
name: 'password',
title: 'Password',
validators: [FlValidators.required()],
widget: TextFormField(
decoration: InputDecoration(border: OutlineInputBorder()),
obscureText: true,
),
),
],
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Flutter Form Example'),
),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Form(
key: _formKey,
child: Column(
children: [
Expanded(
child: FlForm(
formController: _formController,
),
),
SizedBox(height: 20),
ElevatedButton(
onPressed: () async {
if (_formKey.currentState!.validate()) {
final formValues = await _formController.save();
print('Form Submitted: $formValues');
// 你可以在这里处理表单提交逻辑,比如发送到服务器
}
},
child: Text('Submit'),
),
],
),
),
),
);
}
@override
void dispose() {
_formController.dispose();
super.dispose();
}
}
在这个示例中:
- 我们创建了一个
FlFormController
实例来管理表单字段。 - 每个字段都通过
FlFormField
定义,包括字段名、标题、验证器和对应的TextFormField
小部件。 - 使用
Form
小部件包裹FlForm
,并设置一个GlobalKey
来验证表单。 - 在提交按钮的
onPressed
回调中,我们首先验证表单,如果验证通过,则调用_formController.save()
方法来获取表单字段的值。
这个示例展示了如何使用 fl_form
插件来简化表单的构建和管理。你可以根据需要添加更多的字段和验证规则,以及处理表单提交的逻辑。