Flutter文件上传进度管理插件supabase_progress_uploads的使用
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
更多关于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'),
);
}
}
注意事项:
- 你需要替换
YOUR_SUPABASE_URL
和YOUR_ANON_KEY
为你自己的 Supabase 项目 URL 和匿名密钥。 - 你需要确保已经添加了
file_picker
插件来支持文件选择,并在pubspec.yaml
中添加依赖:
dependencies:
file_picker: ^x.y.z # 确保使用最新版本
-
由于
file_picker
插件的pickFiles
方法返回的文件路径在不同平台上可能有所不同,因此你可能需要处理路径兼容性问题。 -
你可以根据实际需要进一步扩展和自定义代码,例如添加更多的错误处理、UI 进度条等。
希望这个示例代码能帮助你理解如何使用 supabase_progress_uploads
插件进行文件上传进度管理。