Flutter表单构建文件选择插件form_builder_file_picker的使用

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

Flutter表单构建文件选择插件form_builder_file_picker的使用

form_builder_file_picker是Flutter中用于创建表单时,提供文件选择功能的一个插件。它与flutter_form_builder包配合使用,可以方便地在表单中添加文件选择字段。以下是关于如何使用这个插件的详细介绍。

特性

  • 自动处理权限:无需手动请求权限,插件会自动处理。
  • 显示图片预览:对于图片类型的文件,可以直接在界面上进行预览。

使用方法

设置

由于此插件依赖于file_picker包,因此需要根据不同的平台(如Android、iOS等)进行特定的设置,请参考file_picker的设置指南

基本用法

import 'package:flutter_form_builder/flutter_form_builder.dart';
import 'package:form_builder_file_picker/form_builder_file_picker.dart';

FormBuilderFilePicker(
  name: "images",
  decoration: InputDecoration(labelText: "Attachments"),
  maxFiles: null,
  previewImages: true,
  onChanged: (val) => print(val),
  typeSelectors: [
    TypeSelector(
      type: FileType.any,
      selector: Row(
        children: <Widget>[
          Icon(Icons.add_circle),
          Padding(
            padding: const EdgeInsets.only(left: 8.0),
            child: Text("Add documents"),
          ),
        ],
      ),
    ),
  ],
  onFileLoading: (val) {
    print(val);
  },
)

特定用途

如果你想在同一表单字段中同时支持文档和图片的选择,可以通过配置typeSelectors参数来实现。例如:

FormBuilderFilePicker(
  name: "attachments",
  previewImages: false,
  allowMultiple: true,
  withData: true,
  typeSelectors: [
    TypeSelector(
      type: FileType.any,
      selector: Row(
        children: <Widget>[
          Icon(Icons.add_circle),
          Padding(
            padding: const EdgeInsets.only(left: 8.0),
            child: Text("Add documents"),
          ),
        ],
      ),
    ),
    if (!kIsWeb)
      TypeSelector(
        type: FileType.image,
        selector: Row(
          children: <Widget>[
            Icon(Icons.add_photo_alternate),
            Padding(
              padding: const EdgeInsets.only(left: 8.0),
              child: Text("Add images"),
            ),
          ],
        ),
      ),
  ]
)

示例代码

下面是一个完整的示例代码,展示了如何将form_builder_file_picker集成到一个简单的Flutter应用中,并实现了基本的功能:

import 'package:flutter/material.dart';
import 'package:flutter_form_builder/flutter_form_builder.dart';
import 'package:form_builder_file_picker/form_builder_file_picker.dart';

void main() => 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: const MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key});

  @override
  MyHomePageState createState() => MyHomePageState();
}

class MyHomePageState extends State<MyHomePage> {
  final _formKey = GlobalKey<FormBuilderState>();
  bool _useCustomFileViewer = true;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('FormBuilder FilePicker Example'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(10),
        child: FormBuilder(
          key: _formKey,
          child: Column(
            children: <Widget>[
              FormBuilderFilePicker(
                name: 'images',
                decoration: const InputDecoration(labelText: 'Attachments'),
                maxFiles: null,
                allowMultiple: true,
                previewImages: true,
                onChanged: (val) => debugPrint(val.toString()),
                typeSelectors: const [
                  TypeSelector(
                    type: FileType.any,
                    selector: Row(
                      children: <Widget>[
                        Icon(Icons.file_upload),
                        Text('Upload'),
                      ],
                    ),
                  )
                ],
                customTypeViewerBuilder: (children) => Row(
                  mainAxisAlignment: MainAxisAlignment.end,
                  children: children,
                ),
                onFileLoading: (val) {
                  debugPrint(val.toString());
                },
                customFileViewerBuilder: _useCustomFileViewer
                    ? (files, filesSetter) =>
                        customFileViewerBuilder(files ?? [], (newValue) {})
                    : null,
              ),
              const SizedBox(height: 20),
              Row(
                mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                children: [
                  ElevatedButton(
                    child: const Text('Submit'),
                    onPressed: () {
                      _formKey.currentState!.save();
                      debugPrint(_formKey.currentState!.value.toString());
                    },
                  ),
                  const Spacer(),
                  ElevatedButton(
                    child: Text(_useCustomFileViewer
                        ? 'Use Default File Viewer'
                        : 'Use Custom File Viewer'),
                    onPressed: () {
                      setState(() => _useCustomFileViewer = !_useCustomFileViewer);
                    },
                  ),
                  const Spacer(),
                  ElevatedButton(
                    child: const Text('Reset'),
                    onPressed: () {
                      setState(
                        () => _formKey.currentState!.reset(),
                      );
                    },
                  ),
                ],
              ),
            ],
          ),
        ),
      ),
    );
  }

  Widget customFileViewerBuilder(
    List<PlatformFile> files,
    FormFieldSetter<List<PlatformFile>> setter,
  ) {
    return files.isEmpty
        ? const Center(child: Text('No files'))
        : ListView.separated(
            shrinkWrap: true,
            itemBuilder: (context, index) {
              return ListTile(
                title: Text(files[index].name),
                trailing: IconButton(
                  icon: const Icon(Icons.delete),
                  onPressed: () {
                    files.removeAt(index);
                    setter.call([...files]);
                  },
                ),
              );
            },
            separatorBuilder: (context, index) =>
                const Divider(color: Colors.blueAccent),
            itemCount: files.length,
          );
  }
}

这段代码展示了一个包含文件选择器的简单页面,用户可以选择多个文件并提交表单。此外,还提供了切换自定义文件查看器和默认文件查看器的功能,以及重置表单按钮。


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

1 回复

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


当然,以下是一个关于如何在Flutter项目中使用form_builder_file_picker插件来构建表单文件选择功能的示例代码。

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

dependencies:
  flutter:
    sdk: flutter
  form_builder_flutter: ^6.0.0  # 请使用最新版本
  form_builder_file_picker: ^4.0.0  # 请使用最新版本

然后,运行flutter pub get来安装这些依赖项。

接下来,你可以在你的Flutter应用中配置和使用form_builder_file_picker。以下是一个完整的示例:

import 'package:flutter/material.dart';
import 'package:form_builder_flutter/form_builder_flutter.dart';
import 'package:form_builder_file_picker/form_builder_file_picker.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Form Builder File Picker Example'),
        ),
        body: MyFormScreen(),
      ),
    );
  }
}

class MyFormScreen extends StatefulWidget {
  @override
  _MyFormScreenState createState() => _MyFormScreenState();
}

class _MyFormScreenState extends State<MyFormScreen> {
  final GlobalKey<FormBuilderState> _fbKey = GlobalKey<FormBuilderState>();

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.all(16.0),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: <Widget>[
          FormBuilder(
            key: _fbKey,
            initialValue: {
              'file_picker': null,  // 初始值可以设置为null
            },
            children: <Widget>[
              FormBuilderFilePicker(
                name: 'file_picker',
                label: 'Choose a file',
                validators: [FormBuilderValidators.required()],
                allowedExtensions: ['.pdf', '.jpg', '.png'],  // 可选的文件扩展名
                maxFileSize: 5 * 1024 * 1024,  // 最大文件大小(5MB)
                decoration: InputDecoration(
                  border: OutlineInputBorder(),
                ),
              ),
            ],
          ),
          SizedBox(height: 20),
          ElevatedButton(
            onPressed: () async {
              // 提交表单
              try {
                Map<String, dynamic> formData = await _fbKey.currentState!.save();
                print('Form Data: $formData');
                // 你可以在这里处理文件上传等操作
              } catch (e) {
                print('Error: $e');
              }
            },
            child: Text('Submit'),
          ),
        ],
      ),
    );
  }
}

在这个示例中,我们创建了一个简单的Flutter应用,其中包含一个表单。表单中只有一个文件选择器字段,用户可以从中选择文件。我们还设置了一些文件选择器的配置,如允许的文件扩展名和最大文件大小。

当用户点击“Submit”按钮时,表单数据将被收集并打印到控制台。你可以根据需要对收集到的文件数据进行进一步处理,例如上传到服务器。

请注意,为了处理文件上传等操作,你可能需要额外的代码和依赖项,例如使用diohttp库进行网络请求。这个示例主要展示了如何使用form_builder_file_picker插件来构建文件选择表单字段。

回到顶部