Flutter文件上传进度管理插件supabase_progress_uploads的使用

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

Flutter文件上传进度管理插件supabase_progress_uploads的使用

插件介绍

supabase_progress_uploads 是一个用于在Flutter中轻松将文件上传到Supabase存储并跟踪进度的插件。它支持单个和多个文件上传,并且提供了暂停、恢复和取消上传的功能。

安装插件

首先,你需要在 pubspec.yaml 文件中添加以下依赖项:

dependencies:
  supabase_progress_uploads: ^1.0.0

初始化上传服务

初始化上传服务时,需要提供Supabase客户端实例和目标存储桶名称。

final supabase = Supabase.instance.client;
final uploadService = SupabaseUploadService(supabase, 'your_bucket_name');

单个文件上传

可以使用 uploadFile 方法来上传单个文件,并通过回调函数跟踪上传进度。

String? url = await uploadService.uploadFile(
  file,
  onUploadProgress: (progress) {
    print('Upload progress: ${progress}%');
  },
);
print('Uploaded file URL: $url');

多个文件上传

同样可以使用 uploadMultipleFiles 方法来上传多个文件,并通过回调函数跟踪总进度。

List<String?> urls = await uploadService.uploadMultipleFiles(
  files,
  onUploadProgress: (progress) {
    print('Total upload progress: ${progress}%');
  },
);
print('Uploaded files URLs: $urls');

使用 SupabaseUploadController 直接控制上传过程

对于更精细的控制,可以直接使用 SupabaseUploadController

final controller = SupabaseUploadController(supabase, 'your_bucket_name');

int fileId = await controller.addFile(file);
controller.startUpload(
  fileId,
  onUploadProgress: (progress) {
    print('Upload progress: ${progress}%');
  },
);
String? url = await controller.getUploadedUrl(fileId);
print('Uploaded file URL: $url');

暂停、恢复和取消上传

可以通过调用相应的方法来控制上传状态。

controller.pauseUpload(fileId);
controller.resumeUpload(fileId);
await controller.cancelUpload(fileId);

示例代码

下面是一个完整的示例代码,展示了如何使用 supabase_progress_uploads 插件进行文件上传操作。

import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
import 'package:supabase_flutter/supabase_flutter.dart';
import 'package:supabase_progress_uploads/supabase_progress_uploads.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Supabase.initialize(
    url: 'YOUR_SUPABASE_URL',
    anonKey: 'YOUR_SUPABASE_ANON_KEY',
  );
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  [@override](/user/override)
  Widget build(BuildContext context) {
    return const MaterialApp(home: UploadExample());
  }
}

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

  [@override](/user/override)
  _UploadExampleState createState() => _UploadExampleState();
}

class _UploadExampleState extends State<UploadExample> {
  final ImagePicker _picker = ImagePicker();
  late SupabaseUploadService _uploadService;
  late SupabaseUploadController _uploadController;
  double _singleProgress = 0.0;
  double _multipleProgress = 0.0;

  [@override](/user/override)
  void initState() {
    super.initState();
    final supabase = Supabase.instance.client;
    supabase.auth.signInAnonymously();
    _uploadService = SupabaseUploadService(supabase, 'your_bucket_name');
    _uploadController = SupabaseUploadController(supabase, 'your_bucket_name');
  }

  Future<void> _uploadSingleFile() async {
    final XFile? image = await _picker.pickImage(source: ImageSource.gallery);
    if (image != null) {
      String? url = await _uploadService.uploadFile(
        image,
        onUploadProgress: (progress) {
          setState(() { _singleProgress = progress; });
        },
      );
      ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text('File Uploaded')));
      print('Uploaded file URL: $url');
    }
  }

  Future<void> _uploadMultipleFiles() async {
    final List<XFile> images = await _picker.pickMultiImage();
    if (image.isNotEmpty) {
      List<String?> urls = await _uploadService.uploadMultipleFiles(
        image,
        onUploadProgress: (progress) {
          setState(() { _multipleProgress = progress; });
        },
      );

      ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text('Files Uploaded')));
      print('Uploaded files URLs: $urls');
    }
  }

  Future<void> _uploadWithController() async {
    final XFile? image = await _picker.pickImage(source: ImageSource.gallery);
    if (image != null) {
      int fileId = await _uploadController.addFile(image);
      _uploadController.startUpload(
        fileId,
        onUploadProgress: (progress) {
          setState(() { _singleProgress = progress; });
        },
      );
      String? url = await _uploadController.getUploadedUrl(fileId);
      ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text('File Uploaded')));
      print('Uploaded file URL: $url');
    }
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Supabase Upload Example')),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            ElevatedButton(
              onPressed: _uploadSingleFile,
              child: const Text('Upload Single File'),
            ),
            Text('Single Progress: ${(_singleProgress).toStringAsFixed(2)}%'),
            const SizedBox(height: 20),
            ElevatedButton(
              onPressed: _uploadMultipleFiles,
              child: const Text('Upload Multiple Files'),
            ),
            Text('Multiple Progress: ${(_multipleProgress).toStringAsFixed(2)}%'),
            const SizedBox(height: 20),
            ElevatedButton(
              onPressed: _uploadWithController,
              child: const Text('Upload with Controller'),
            ),
          ],
        ),
      ),
    );
  }

  [@override](/user/override)
  void dispose() {
    _uploadService.dispose();
    super.dispose();
  }
}

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

1 回复

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


当然,下面是一个关于如何使用 supabase_progress_uploads 插件在 Flutter 中管理文件上传进度的示例代码。supabase_progress_uploads 插件允许你在使用 Supabase 进行文件上传时跟踪上传进度。

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

dependencies:
  flutter:
    sdk: flutter
  supabase_flutter: ^x.y.z  # 确保使用最新版本
  supabase_progress_uploads: ^x.y.z  # 确保使用最新版本

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

接下来是完整的示例代码,展示如何使用 supabase_progress_uploads 进行文件上传并管理上传进度:

import 'package:flutter/material.dart';
import 'package:supabase_flutter/supabase_flutter.dart';
import 'package:supabase_progress_uploads/supabase_progress_uploads.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Supabase File Upload Progress Example'),
        ),
        body: FileUploadPage(),
      ),
    );
  }
}

class FileUploadPage extends StatefulWidget {
  @override
  _FileUploadPageState createState() => _FileUploadPageState();
}

class _FileUploadPageState extends State<FileUploadPage> {
  final SupabaseClient supabase = SupabaseClient(
    url: 'YOUR_SUPABASE_URL',
    anonKey: 'YOUR_ANON_KEY'
  );

  final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
  File? _selectedFile;

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.all(16.0),
      child: Form(
        key: _formKey,
        child: Column(
          children: <Widget>[
            TextFormField(
              decoration: InputDecoration(labelText: 'File Name (for reference)'),
              enabled: false,
              initialValue: _selectedFile?.path.split('/').last,
            ),
            SizedBox(height: 16),
            FilePickerField(
              onFileChange: (File file) {
                setState(() {
                  _selectedFile = file;
                });
              },
            ),
            SizedBox(height: 16),
            ElevatedButton(
              onPressed: () async {
                if (_formKey.currentState!.validate()) {
                  if (_selectedFile != null) {
                    await uploadFileWithProgress();
                  } else {
                    ScaffoldMessenger.of(context).showSnackBar(
                      SnackBar(content: Text('Please select a file')),
                    );
                  }
                }
              },
              child: Text('Upload File'),
            ),
          ],
        ),
      ),
    );
  }

  Future<void> uploadFileWithProgress() async {
    try {
      final uploadTask = supabase.storage
        .from('your_bucket_name')
        .upload(_selectedFile!.path, _selectedFile!.path.split('/').last, metadata: {
          'content-type': _getMimeType(_selectedFile!.path),
        });

      uploadTask.onProgress((progress) {
        print('Upload progress: ${progress.percentage}%');
        // 你可以在这里更新UI,例如显示进度条
        setState(() {
          // 例如,更新一个进度条的值
          // progressBarValue = progress.percentage;
        });
      });

      final result = await uploadTask.complete();
      print('Upload result: $result');
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(content: Text('File uploaded successfully')),
      );
    } catch (e) {
      print('Error uploading file: $e');
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(content: Text('Error uploading file')),
      );
    }
  }

  String _getMimeType(String filePath) {
    String extension = filePath.split('.').last;
    switch (extension) {
      case 'jpg':
      case 'jpeg':
        return 'image/jpeg';
      case 'png':
        return 'image/png';
      // 你可以根据需要添加更多MIME类型
      default:
        return 'application/octet-stream';
    }
  }
}

// FilePickerField 是一个自定义组件,用于选择文件,这里简单实现一个
class FilePickerField extends StatefulWidget {
  final ValueChanged<File> onFileChange;

  FilePickerField({required this.onFileChange});

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

class _FilePickerFieldState extends State<FilePickerField> {
  File? _pickedFile;

  Future<void> _pickFile() async {
    final result = await FilePicker.platform.pickFiles(type: FileType.any);

    if (result != null && result.files.isNotEmpty) {
      final file = File(result.files.first.path!);
      widget.onFileChange(file);
      setState(() {
        _pickedFile = file;
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return ElevatedButton(
      onPressed: _pickFile,
      child: Text('Select File'),
    );
  }
}

注意事项

  1. 你需要替换 YOUR_SUPABASE_URLYOUR_ANON_KEY 为你自己的 Supabase 项目 URL 和匿名密钥。
  2. 你需要确保已经添加了 file_picker 插件来支持文件选择,并在 pubspec.yaml 中添加依赖:
dependencies:
  file_picker: ^x.y.z  # 确保使用最新版本
  1. 由于 file_picker 插件的 pickFiles 方法返回的文件路径在不同平台上可能有所不同,因此你可能需要处理路径兼容性问题。

  2. 你可以根据实际需要进一步扩展和自定义代码,例如添加更多的错误处理、UI 进度条等。

希望这个示例代码能帮助你理解如何使用 supabase_progress_uploads 插件进行文件上传进度管理。

回到顶部