You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 14:25:24