如何通过Flutter应用从Supabase Storage获取并展示所有图片?
Flutter 展示 Supabase Storage 所有图片完整实现
1. 添加依赖
在pubspec.yaml中添加所需依赖:
dependencies: flutter: sdk: flutter supabase_flutter: ^2.0.0 # 请使用最新版本 cached_network_image: ^3.2.3 # 用于图片缓存与优化加载体验
执行flutter pub get安装依赖。
2. 初始化 Supabase
在main.dart的main函数中完成初始化:
import 'package:flutter/material.dart'; import 'package:supabase_flutter/supabase_flutter.dart'; void main() async { WidgetsFlutterBinding.ensureInitialized(); await Supabase.initialize( url: '你的Supabase项目URL', anonKey: '你的Supabase匿名密钥', ); runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( title: 'Supabase Storage 图片展示', theme: ThemeData(primarySwatch: Colors.blue), home: const ImageGalleryScreen(), ); } }
3. 核心实现:获取并展示所有图片
创建一个ImageGalleryScreen组件,负责加载存储桶中的图片并展示:
class ImageGalleryScreen extends StatefulWidget { const ImageGalleryScreen({super.key}); @override State<ImageGalleryScreen> createState() => _ImageGalleryScreenState(); } class _ImageGalleryScreenState extends State<ImageGalleryScreen> { final supabase = Supabase.instance.client; List<String> imageUrls = []; bool isLoading = true; String? errorMessage; @override void initState() { super.initState(); _loadImages(); } Future<void> _loadImages() async { try { // 替换为你的存储桶名称 const bucketName = 'images'; // 获取存储桶中所有文件 final files = await supabase.storage.from(bucketName).list(); // 过滤出图片文件(可选,根据你的文件扩展名调整) final imageFiles = files.where((file) => file.name.endsWith('.jpg') || file.name.endsWith('.jpeg') || file.name.endsWith('.png') || file.name.endsWith('.webp') ).toList(); // 生成图片可访问URL setState(() { imageUrls = imageFiles.map((file) { // 公开桶使用 getPublicUrl return supabase.storage.from(bucketName).getPublicUrl(file.name); // 如果是私有桶,使用带签名的URL(有效期可自定义,这里设为3600秒) // return supabase.storage.from(bucketName).createSignedUrl(file.name, 3600); }).toList(); isLoading = false; }); } catch (e) { setState(() { errorMessage = e.toString(); isLoading = false; }); } } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('图片画廊')), body: isLoading ? const Center(child: CircularProgressIndicator()) : errorMessage != null ? Center(child: Text('加载失败: $errorMessage')) : GridView.builder( padding: const EdgeInsets.all(8), gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: 2, crossAxisSpacing: 8, mainAxisSpacing: 8, ), itemCount: imageUrls.length, itemBuilder: (context, index) { return CachedNetworkImage( imageUrl: imageUrls[index], fit: BoxFit.cover, placeholder: (context, url) => const Center(child: CircularProgressIndicator()), errorWidget: (context, url, error) => const Icon(Icons.broken_image), ); }, ), ); } }
关键注意事项
- 存储桶权限:如果使用公开桶,需确保存储桶的
public权限已开启;如果是私有桶,用户需要先完成认证(可使用supabase.auth.signInWithPassword等方法)才能生成有效签名URL。 - 文件过滤:代码中添加了图片扩展名过滤,可根据实际需求调整或移除。
- 错误处理:示例中包含了基础的错误捕获与展示,可根据项目需求扩展更友好的错误提示。
内容的提问来源于stack exchange,提问作者Muhammed Shoaib
相关产品推荐
相关产品推荐

