Flutter如何从Application Document Directory读取存储的图片/截图
Flutter 读取应用文档目录截图实现内置相册方案
- 前置依赖准备:除了你已经在用的
screenshot包,只需要额外引入path_provider用于定位系统应用目录即可,Flutter 原生自带本地文件图片加载能力,不需要额外引入图片处理依赖。在pubspec.yaml中添加依赖:
dependencies: flutter: sdk: flutter screenshot: ^你当前使用的版本 path_provider: ^2.1.0 # 选用最新稳定版即可
- 统一封装路径获取逻辑:存图和取图必须使用完全一致的路径规则,避免因为路径不匹配找不到文件,封装一个通用的截图目录获取方法:
import 'package:path_provider/path_provider.dart'; import 'dart:io'; // 获取统一的截图存储目录 Future<Directory> getScreenshotStorageDir() async { // 获取系统应用文档目录 final Directory appDocDir = await getApplicationDocumentsDirectory(); // 可选:在应用文档目录下单独建screenshots子文件夹存放截图,方便管理 final Directory screenshotDir = Directory('${appDocDir.path}/app_screenshots'); // 目录不存在时递归创建 if (!await screenshotDir.exists()) { await screenshotDir.create(recursive: true); } return screenshotDir; }
注意:调用
screenshot包的captureAndSave方法存截图时,直接把上述方法返回的目录路径作为保存路径参数传入即可。如果你之前存图没有创建子文件夹,直接返回appDocDir即可,核心是存、取两端路径规则完全一致。
- 读取目录下所有截图文件:相册页面加载时遍历目标目录,过滤出图片文件即可,可按需对文件排序:
Future<List<File>> loadAllScreenshots() async { final Directory screenshotDir = await getScreenshotStorageDir(); // 遍历目录下所有文件实体 final List<FileSystemEntity> entities = await screenshotDir.list().toList(); // 过滤出图片格式文件,如果你存的都是固定格式png可以跳过后缀判断 final List<File> imageFiles = entities .whereType<File>() .where((file) => file.path.endsWith('.png') || file.path.endsWith('.jpg')) .toList(); // 可选:按文件修改时间倒序,最新截图排在最前面 imageFiles.sort((a, b) => b.lastModifiedSync().compareTo(a.lastModifiedSync())); return imageFiles; }
- 页面内加载展示图片:直接使用Flutter内置的
Image.file组件加载File对象即可,不需要做额外的路径转码:
// 内置相册页面示例 class InnerAlbumPage extends StatefulWidget { const InnerAlbumPage({super.key}); @override State<InnerAlbumPage> createState() => _InnerAlbumPageState(); } class _InnerAlbumPageState extends State<InnerAlbumPage> { late Future<List<File>> _screenshotListFuture; @override void initState() { super.initState(); _screenshotListFuture = loadAllScreenshots(); } // 新增截图后可以调用这个方法刷新列表 void refreshAlbum() { setState(() { _screenshotListFuture = loadAllScreenshots(); }); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('内置相册')), body: FutureBuilder<List<File>>( future: _screenshotListFuture, builder: (context, snapshot) { if (snapshot.connectionState == ConnectionState.waiting) { return const Center(child: CircularProgressIndicator()); } if (!snapshot.hasData || snapshot.data!.isEmpty) { return const Center(child: Text('暂无保存的截图')); } final List<File> screenshots = snapshot.data!; // 用网格布局展示所有截图 return GridView.builder( padding: const EdgeInsets.all(8), gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: 3, crossAxisSpacing: 4, mainAxisSpacing: 4, ), itemCount: screenshots.length, itemBuilder: (context, index) { return Image.file( screenshots[index], fit: BoxFit.cover, ); }, ); }, ), ); } }
- 常见踩坑点:
- Application Document Directory是应用私有目录,Android、iOS端读写该目录都不需要额外申请存储权限
- 如果需要读取单张已知文件名的截图,不需要遍历目录,直接拼接路径生成File对象即可:
File('${(await getScreenshotStorageDir()).path}/目标文件名.png') - 不要硬编码目录路径,不同系统版本、不同平台的应用文档目录绝对路径存在差异,必须通过
path_provider动态获取
内容的提问来源于stack exchange,提问作者mango
相关产品推荐
相关产品推荐

