Flutter项目如何将image_picker替换为file_picker实现多图上传Firebase
Flutter多图批量上传实现方案
修改步骤
- 第一步:更新依赖配置
在pubspec.yaml中移除原有image_picker依赖,新增file_picker依赖,同时确保已有firebase_core、firebase_storage、path依赖。 - 第二步:替换导入声明
移除image_picker的导入,新增file_picker和dart:io的导入。 - 第三步:改造上传逻辑
将原有的单张选图逻辑替换为多选逻辑,使用Future.wait实现批量并行上传,提升上传效率。 - 第四步:保留原有逻辑
图片加载、删除以及UI展示逻辑无需修改,可直接复用原有代码。
完整修改后代码
import 'dart:io'; import 'package:flutter/material.dart'; import 'package:firebase_core/firebase_core.dart'; import 'package:firebase_storage/firebase_storage.dart'; import 'package:path/path.dart' as path; import 'package:file_picker/file_picker.dart'; void main() async { WidgetsFlutterBinding.ensureInitialized(); await Firebase.initializeApp(); runApp(MyApp()); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( debugShowCheckedModeBanner: false, title: 'Kindacode.com', theme: ThemeData(primarySwatch: Colors.green), home: HomePage(), ); } } class HomePage extends StatefulWidget { @override _HomePageState createState() => _HomePageState(); } class _HomePageState extends State<HomePage> { FirebaseStorage storage = FirebaseStorage.instance; Future<void> _upload(String inputSource) async { try { List<File> selectedFiles = []; if (inputSource == 'camera') { FilePickerResult? result = await FilePicker.platform.pickFiles( type: FileType.image, source: FileSource.camera, ); if (result != null && result.files.single.path != null) { selectedFiles.add(File(result.files.single.path!)); } } else { FilePickerResult? result = await FilePicker.platform.pickFiles( type: FileType.image, allowMultiple: true, ); if (result != null) { selectedFiles = result.paths.map((path) => File(path!)).toList(); } } if (selectedFiles.isEmpty) return; await Future.wait(selectedFiles.map((imageFile) async { final String fileName = path.basename(imageFile.path); await storage.ref(fileName).putFile( imageFile, SettableMetadata(customMetadata: { 'uploaded_by': 'A bad guy', 'description': 'Some description...' })); })); setState(() {}); } catch (err) { print(err); } } Future<List<Map<String, dynamic>>> _loadImages() async { List<Map<String, dynamic>> files = []; final ListResult result = await storage.ref().list(); final List<Reference> allFiles = result.items; await Future.forEach<Reference>(allFiles, (file) async { final String fileUrl = await file.getDownloadURL(); final FullMetadata fileMeta = await file.getMetadata(); files.add({ "url": fileUrl, "path": file.fullPath, "uploaded_by": fileMeta.customMetadata?['uploaded_by'] ?? 'Nobody', "description": fileMeta.customMetadata?['description'] ?? 'No description' }); }); return files; } Future<void> _delete(String ref) async { await storage.ref(ref).delete(); setState(() {}); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('Kindacode.com'), ), body: Padding( padding: const EdgeInsets.all(20), child: Column( children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ ElevatedButton.icon( onPressed: () => _upload('camera'), icon: Icon(Icons.camera), label: Text('camera')), ElevatedButton.icon( onPressed: () => _upload('gallery'), icon: Icon(Icons.library_add), label: Text('Gallery')), ], ), Expanded( child: FutureBuilder( future: _loadImages(), builder: (context, AsyncSnapshot<List<Map<String, dynamic>>> snapshot) { if (snapshot.connectionState == ConnectionState.done) { return ListView.builder( itemCount: snapshot.data?.length ?? 0, itemBuilder: (context, index) { final Map<String, dynamic> image = snapshot.data![index]; return Card( margin: EdgeInsets.symmetric(vertical: 10), child: ListTile( dense: false, leading: Image.network(image['url']), title: Text(image['uploaded_by']), subtitle: Text(image['description']), trailing: IconButton( onPressed: () => _delete(image['path']), icon: Icon( Icons.delete, color: Colors.red, ), ), ), ); }, ); } return Center( child: CircularProgressIndicator(), ); }, ), ), ], ), ), ); } }
内容的提问来源于stack exchange,提问作者Ankit Kumar
相关产品推荐
相关产品推荐

