Flutter表单构建图片选择器插件form_builder_image_picker的使用
Flutter表单构建图片选择器插件form_builder_image_picker的使用
概述
form_builder_image_picker
是一个用于Flutter FormBuilder的图片选择字段插件,它允许用户从图库或相机中选择图片,并在表单中显示这些图片。该插件支持多种图片类型(如 Uint8List
, XFile
, String
(url), 或 ImageProvider
),并且可以配置为仅使用特定的图片选择源。
主要特性
- 图片选择:可以从图库或相机中选择图片。
- 表单展示:所选图片可以直接在表单中展示。
- 多种图片类型支持:支持
Uint8List
,XFile
,String
(url), 或ImageProvider
等类型的图片。
使用方法
设置
由于此插件依赖于 image_picker
包,因此需要按照 image_picker 安装指南进行平台特定的设置。
基本用法
下面是一个简单的例子,展示了如何在表单中添加一个图片选择器:
FormBuilder(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
FormBuilderImagePicker(
name: 'photos',
decoration: const InputDecoration(labelText: 'Pick Photos'),
maxImages: 1,
),
],
),
)
限制选择来源
如果想要限制图片只能从图库中选择,可以这样做:
FormBuilder(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
FormBuilderImagePicker(
name: 'noCamera',
availableImageSources: const [ImageSourceOption.gallery],
),
],
),
)
示例代码
以下是一个更完整的示例,展示了如何创建一个包含多个图片选择器的表单,并且每个选择器都有不同的配置选项:
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_form_builder/flutter_form_builder.dart';
import 'package:form_builder_image_picker/form_builder_image_picker.dart';
Future<void> main() async {
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,
),
home: MyHomePage(),
);
}
}
class ApiImage {
final String imageUrl;
final String id;
ApiImage({
required this.imageUrl,
required this.id,
});
}
class MyHomePage extends StatelessWidget {
final _formKey = GlobalKey<FormBuilderState>();
MyHomePage({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('FormBuilderImagePicker Example'),
),
body: Padding(
padding: const EdgeInsets.all(8.0),
child: Center(
child: FormBuilder(
key: _formKey,
child: SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
// 多张图片选择器
FormBuilderImagePicker(
name: 'photos',
displayCustomType: (obj) => obj is ApiImage ? obj.imageUrl : obj,
decoration: const InputDecoration(labelText: 'Pick Photos'),
maxImages: 5,
previewAutoSizeWidth: true,
previewMargin: const EdgeInsetsDirectional.only(end: 8),
fit: BoxFit.cover,
initialValue: [
'https://images.pexels.com/photos/7078045/pexels-photo-7078045.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260',
const Text('this is an image\nas a widget !'),
ApiImage(
id: 'whatever',
imageUrl: 'https://images.pexels.com/photos/8311418/pexels-photo-8311418.jpeg?auto=compress&cs=tinysrgb&dpr=3&h=750&w=1260',
),
],
),
const SizedBox(height: 15),
// 单张图片选择器,带装饰
FormBuilderImagePicker(
name: 'singlePhotoWithDecoration',
displayCustomType: (obj) => obj is ApiImage ? obj.imageUrl : obj,
decoration: const InputDecoration(
labelText: 'Pick Single Photo With Decoration Visible',
),
showDecoration: true,
maxImages: 1,
previewAutoSizeWidth: true,
initialValue: const [
'https://images.pexels.com/photos/7078045/pexels-photo-7078045.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260',
],
),
const SizedBox(height: 15),
const Text(
'Single Photo with no decoration, and previewAutoSizeWidth=true'),
// 单张图片选择器,不带装饰
FormBuilderImagePicker(
name: 'singlePhoto',
displayCustomType: (obj) => obj is ApiImage ? obj.imageUrl : obj,
showDecoration: false,
maxImages: 1,
previewAutoSizeWidth: true,
initialValue: const [
'https://images.pexels.com/photos/7078045/pexels-photo-7078045.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260',
],
),
const SizedBox(height: 15),
const Text(
'Single Photo similar to CircleAvatar, using transformImageWidget',
),
// 圆形头像样式的图片选择器
FormBuilderImagePicker(
name: 'singleAvatarPhoto',
displayCustomType: (obj) => obj is ApiImage ? obj.imageUrl : obj,
decoration: const InputDecoration(
labelText: 'Pick Photos',
),
transformImageWidget: (context, displayImage) => Card(
shape: const CircleBorder(),
clipBehavior: Clip.antiAlias,
child: SizedBox.expand(
child: displayImage,
),
),
showDecoration: false,
maxImages: 1,
previewAutoSizeWidth: false,
initialValue: const [
'https://images.pexels.com/photos/7078045/pexels-photo-7078045.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260',
],
),
const SizedBox(height: 15),
// 自定义样式的选择器
FormBuilderImagePicker(
name: 'fieldCustomization',
decoration: const InputDecoration(labelText: 'Pick Photos'),
previewAutoSizeWidth: true,
fit: BoxFit.cover,
backgroundColor: Colors.black54,
iconColor: Colors.white,
icon: Icons.ac_unit_rounded,
),
const SizedBox(height: 15),
// 只能从相机选择图片
FormBuilderImagePicker(
name: 'onlyCamera',
decoration: const InputDecoration(
labelText: 'Pick Photos (only from camera)'),
availableImageSources: const [ImageSourceOption.camera],
),
const SizedBox(height: 15),
// 只能从相册选择图片
FormBuilderImagePicker(
name: 'onlyGallery',
decoration: const InputDecoration(
labelText: 'Pick Photos (only from gallery)'),
availableImageSources: const [ImageSourceOption.gallery],
),
// 使用 CupertinoActionSheet 作为选择器
FormBuilderImagePicker(
decoration: const InputDecoration(
labelText: 'Pick Photos (with custom view)'),
name: 'CupertinoActionSheet',
optionsBuilder: (cameraPicker, galleryPicker) =>
CupertinoActionSheet(
title: const Text('Image'),
message: const Text('Pick an image from given options'),
actions: [
CupertinoActionSheetAction(
isDefaultAction: true,
onPressed: () {
cameraPicker();
},
child: const Text('Camera'),
),
CupertinoActionSheetAction(
isDefaultAction: true,
onPressed: () {
galleryPicker();
},
child: const Text('Gallery'),
)
],
),
onTap: (child) => showCupertinoModalPopup(
context: context,
builder: (context) => child,
),
),
// 自定义预览布局
FormBuilderImagePicker(
name: 'customPreview',
maxImages: null,
previewBuilder: (context, images, addButton) =>
ConstrainedBox(
constraints: const BoxConstraints(
minHeight: 130,
maxHeight: 500,
),
child: GridView.extent(
maxCrossAxisExtent: 130,
mainAxisSpacing: 4,
crossAxisSpacing: 4,
children: [...images, if (addButton != null) addButton],
),
),
),
// 提交按钮
ElevatedButton(
child: const Text('Submit'),
onPressed: () {
if (_formKey.currentState?.saveAndValidate() == true) {
debugPrint(_formKey.currentState!.value.toString());
}
},
),
// 重置按钮
ElevatedButton(
child: const Text('Reset'),
onPressed: () {
_formKey.currentState?.reset();
},
)
],
),
),
),
),
),
);
}
}
支持与贡献
如果您遇到问题或有改进建议,可以通过以下方式参与和支持:
- 提问和回答:可以在 GitHub讨论区 或 StackOverflow 上提问或搜索答案。
- 捐赠:您还可以通过 OpenCollective 成为赞助者或捐赠给Flutter Form Builder生态系统。
希望这个插件能够帮助您更方便地在Flutter应用中处理图片选择功能!
更多关于Flutter表单构建图片选择器插件form_builder_image_picker的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter表单构建图片选择器插件form_builder_image_picker的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是一个关于如何在Flutter中使用form_builder_image_picker
插件来构建带有图片选择功能的表单的示例代码。
首先,确保你已经在pubspec.yaml
文件中添加了form_builder_flutter
和form_builder_image_picker
的依赖:
dependencies:
flutter:
sdk: flutter
form_builder_flutter: ^6.0.0 # 请检查最新版本
form_builder_image_picker: ^6.0.0 # 请检查最新版本
然后,在你的Flutter项目中,你可以按照以下步骤来构建表单,并包含图片选择器:
- 导入必要的包:
import 'package:flutter/material.dart';
import 'package:form_builder_flutter/form_builder_flutter.dart';
import 'package:form_builder_image_picker/form_builder_image_picker.dart';
- 定义表单字段:
final GlobalKey<FormBuilderState> _fbKey = GlobalKey<FormBuilderState>();
List<FormBuilderField> fields = [
FormBuilderImagePickerField(
name: "photo",
label: "Select Image",
validators: [FormBuilderValidators.required()],
decoration: InputDecoration(border: OutlineInputBorder()),
),
// 你可以在这里添加其他表单字段
];
- 构建表单:
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text("Form with Image Picker"),
),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: FormBuilder(
key: _fbKey,
initialValues: {
// 你可以在这里设置初始值
},
fields: fields,
onSubmit: (values) {
// 处理表单提交
print(values);
},
),
),
),
);
}
}
- 处理图片显示:
如果你需要在表单提交后显示选择的图片,你可以通过values
字典获取图片路径,然后使用Image.file
或Image.network
来显示图片(如果是网络图片URL)。以下是一个简单的例子,假设你有一个页面用来显示提交的表单数据:
class FormDataDisplay extends StatelessWidget {
final Map<String, dynamic> formData;
FormDataDisplay({required this.formData});
@override
Widget build(BuildContext context) {
String? imagePath = formData['photo'] as String?;
return Scaffold(
appBar: AppBar(
title: Text("Form Data Display"),
),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text("Image Path: $imagePath"),
if (imagePath != null)
Image.file(File(imagePath!)) // 如果是本地图片
// 如果是网络图片,可以使用 Image.network(imagePath!)
],
),
),
);
}
}
在onSubmit
回调中,你可以导航到一个新的页面来显示这些数据:
onSubmit: (values) {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => FormDataDisplay(formData: values)),
);
},
以上是一个基本的示例,展示了如何使用form_builder_image_picker
插件在Flutter中构建带有图片选择功能的表单。你可以根据需要进一步自定义和扩展这个示例。