Flutter文件上传插件flutter_file_uploader的使用

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

Flutter文件上传插件flutter_file_uploader的使用

flutter_file_uploader 是一个用于处理文件上传的Flutter插件。它提供了一组易于使用的组件来管理和显示文件上传状态。

特性

  • FileUploader: 管理文件添加和移除逻辑。
  • FileCard: 显示文件上传进度。
  • FileUploadControllerProvider: 提供文件上传业务逻辑,如状态(加载、完成等)和进度。

使用方法

基本用法

如果你只关注UI细节,可以使用 FileUploaderProvidedFileCard 组件。

import 'package:flutter/material.dart';
import 'package:flutter_file_uploader/flutter_file_uploader.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: FileUploaderExample(),
    );
  }
}

class FileUploaderExample extends StatefulWidget {
  @override
  _FileUploaderExampleState createState() => _FileUploaderExampleState();
}

class _FileUploaderExampleState extends State<FileUploaderExample> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('File Uploader Example')),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: FileUploader(
          builder: (context, ref) {
            return ProvidedFileCard(
              ref: ref,
              content: Text("filename"),
            );
          },
          onPressedAddFiles: () async {
            // Implement file selection logic here
          },
          onFileAdded: (file) async {
            // Implement custom upload handler creation here
          },
          onFileUploaded: (file) {
            print("file uploaded ${file.id}");
          },
          onFileRemoved: (file) {
            print("file removed ${file.id}");
          },
          placeholder: Text("add a file"),
        ),
      ),
    );
  }
}

自定义Widget

你也可以在 FileUploader.builder 回调中创建自定义Widget来管理上传、重试和删除文件。

FileUploader(
  builder: (context, ref) {
    return MyCustomFileCard(
      ref: ref,
    );
  },
  onPressedAddFiles: () async {
    // Implement file selection logic here
  },
  onFileAdded: (file) async {
    // Implement custom upload handler creation here
  },
  onFileUploaded: (file) {
    print("file uploaded ${file.id}");
  },
  onFileRemoved: (file) {
    print("file removed ${file.id}");
  },
  placeholder: Text("add a file"),
)

示例

example 项目中,你可以找到一些实际应用的例子:

  • default: 使用 FileUploaderProvidedFileCard 的最简单例子。
  • default_restorable_chunked: 使用不同的处理器 InMemoryRestorableChunkedFileUploadHandler
  • self_ref_management: 自定义文件上传状态管理(不使用 ProvidedFileCard)。

Widgets

  • FileUploader: 管理文件添加和移除逻辑。
  • Providers: 使用 provider 库插入和消费 FileUploadControllerModel
  • FileCard: 显示文件上传进度。
  • ProvidedFileCard: 结合 FileCardFileUploadControllerProvider

截图

请查看 screenshotvideo 获取更多视觉信息。

通过以上示例和说明,你应该能够快速上手并使用 flutter_file_uploader 插件进行文件上传功能的开发。


更多关于Flutter文件上传插件flutter_file_uploader的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter文件上传插件flutter_file_uploader的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是如何在Flutter项目中使用flutter_file_uploader插件进行文件上传的示例代码。这个插件允许你在后台上传文件,而不会阻塞UI线程。

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

dependencies:
  flutter:
    sdk: flutter
  flutter_file_uploader: ^x.y.z  # 请替换为最新版本号

然后运行flutter pub get来安装依赖。

配置Android和iOS

Android

android/app/src/main/AndroidManifest.xml中添加以下权限:

<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

iOS

ios/Runner/Info.plist中添加以下权限(如果需要访问照片库等):

<key>NSPhotoLibraryAddUsageDescription</key>
<string>需要访问照片库以选择文件上传</string>
<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
</dict>

示例代码

以下是一个完整的示例,展示如何使用flutter_file_uploader插件进行文件上传:

import 'package:flutter/material.dart';
import 'package:flutter_file_uploader/flutter_file_uploader.dart';
import 'dart:io';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: UploadPage(),
    );
  }
}

class UploadPage extends StatefulWidget {
  @override
  _UploadPageState createState() => _UploadPageState();
}

class _UploadPageState extends State<UploadPage> {
  final FilePicker _picker = FilePicker();
  FTPUploader? _uploader;

  @override
  void initState() {
    super.initState();
    // 初始化FTPUploader
    _uploader = FTPUploader(
      baseUrl: 'http://your-server-url/upload', // 替换为你的服务器URL
      headers: <String, String>{
        'Authorization': 'Bearer YOUR_ACCESS_TOKEN', // 如果需要认证,添加header
      },
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('文件上传示例'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            ElevatedButton(
              onPressed: _pickFile,
              child: Text('选择文件'),
            ),
            SizedBox(height: 20),
            ElevatedButton(
              onPressed: _uploadFile,
              child: Text('上传文件'),
              enabled: _picker.path != null, // 只有选择了文件后才启用上传按钮
            ),
          ],
        ),
      ),
    );
  }

  Future<void> _pickFile() async {
    File? file = await _picker.getFile(type: FileType.any);
    if (file != null) {
      setState(() {
        _picker.path = file.path;
      });
    }
  }

  Future<void> _uploadFile() async {
    if (_picker.path == null) return;

    var uploadId = Uuid().v4(); // 生成一个唯一的上传ID
    var uploadTask = _uploader!.uploadFile(
      filePath: _picker.path!,
      fileKey: 'file',
      data: {
        'upload_id': uploadId,
      },
      onProgress: (progress, response) {
        print('上传进度: $progress%');
        if (response != null) {
          print('服务器响应: ${response.body}');
        }
      },
      onCompleted: (response, error) {
        if (response != null) {
          print('上传完成: ${response.body}');
        } else if (error != null) {
          print('上传错误: $error');
        }
      },
      onCancelled: (cancelledObject) {
        print('上传已取消');
      },
    );

    // 如果需要取消上传,可以调用:uploadTask.cancel();
  }
}

class FilePicker {
  String? path;

  Future<File?> getFile({FileType type = FileType.any}) async {
    var result = await FilePickerResult.platform.pickFiles(
      type: type,
      allowMultiple: false,
    );

    if (result != null && result.files.isNotEmpty) {
      var file = File(result.files.first.path!);
      path = file.path;
      return file;
    } else {
      return null;
    }
  }
}

enum FileType {
  image,
  video,
  audio,
  any,
}

注意事项

  1. 服务器配置:确保你的服务器端已经配置好接收文件上传的接口。
  2. 权限处理:在真实应用中,需要处理文件访问权限请求(尤其是在Android上)。
  3. 错误处理:示例代码中省略了详细的错误处理逻辑,实际项目中应添加必要的错误处理。

这个示例展示了如何使用flutter_file_uploader插件进行文件选择和上传。根据你的需求,你可能需要调整服务器URL、请求头和其他参数。

回到顶部