Flutter表单构建图片选择器插件form_builder_image_picker的使用

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

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();
                    },
                  )
                ],
              ),
            ),
          ),
        ),
      ),
    );
  }
}

支持与贡献

如果您遇到问题或有改进建议,可以通过以下方式参与和支持:

希望这个插件能够帮助您更方便地在Flutter应用中处理图片选择功能!


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

1 回复

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


当然,以下是一个关于如何在Flutter中使用form_builder_image_picker插件来构建带有图片选择功能的表单的示例代码。

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

dependencies:
  flutter:
    sdk: flutter
  form_builder_flutter: ^6.0.0  # 请检查最新版本
  form_builder_image_picker: ^6.0.0  # 请检查最新版本

然后,在你的Flutter项目中,你可以按照以下步骤来构建表单,并包含图片选择器:

  1. 导入必要的包
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';
  1. 定义表单字段
final GlobalKey<FormBuilderState> _fbKey = GlobalKey<FormBuilderState>();

List<FormBuilderField> fields = [
  FormBuilderImagePickerField(
    name: "photo",
    label: "Select Image",
    validators: [FormBuilderValidators.required()],
    decoration: InputDecoration(border: OutlineInputBorder()),
  ),
  // 你可以在这里添加其他表单字段
];
  1. 构建表单
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);
            },
          ),
        ),
      ),
    );
  }
}
  1. 处理图片显示

如果你需要在表单提交后显示选择的图片,你可以通过values字典获取图片路径,然后使用Image.fileImage.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中构建带有图片选择功能的表单。你可以根据需要进一步自定义和扩展这个示例。

回到顶部