Flutter开发自定义图库时Image.memory组件加载报错无法编译
问题原因
- 编译错误由空安全类型不匹配导致:
- photo_manager 2.1.2是适配Dart空安全的版本,
thumbnailDataWithSize方法返回值为Future<Uint8List?>,存在返回null的可能(缩略图生成失败、资源损坏、权限异常等场景都会返回null) - 代码中
FutureBuilder未指定泛型,Dart推断snapshot.data类型为Object?,既不符合Image.memory要求的Uint8List入参类型,也未做非空校验,直接传参就会触发编译报错 - 代码中定义的
loadImage、bytesToImage两个方法没有任何调用,属于冗余代码,可直接删除。
- photo_manager 2.1.2是适配Dart空安全的版本,
修复方案
- 为
FutureBuilder指定明确的Uint8List?泛型,在使用snapshot.data前增加非空判断,通过类型校验后再传入Image.memory - 增加图片加载失败的兜底逻辑,避免异常场景下UI报错
- 删除无用冗余代码
修复后核心代码
替换原有FutureBuilder部分代码即可:
FutureBuilder<Uint8List?>( future: asset.thumbnailDataWithSize(const ThumbnailSize(200, 200)), builder: (BuildContext context, AsyncSnapshot<Uint8List?> snapshot) { if (snapshot.connectionState == ConnectionState.done && snapshot.data != null) { return Stack( children: [ Positioned.fill( child: Image.memory( snapshot.data!, fit: BoxFit.cover, errorBuilder: (_, __, ___) => ColoredBox(color: Colors.grey[200]!), ), ), if (asset.type == AssetType.video) const Align( alignment: Alignment.bottomRight, child: Padding( padding: EdgeInsets.only(right: 5, bottom: 5), child: Icon(Icons.videocam, color: Colors.white), ), ), ], ); } return ColoredBox(color: Colors.grey[200]!); }, )
可选优化
- 现有逻辑直接把生成的Widget存入
_mediaList列表,分页加载后列表会持续膨胀占用内存,建议改为存储List<AssetEntity>类型的原始媒体数据,在GridView.builder的itemBuilder中临时构建缩略图组件,内存表现更好 - 滚动监听逻辑可增加防抖判断,避免快速滚动时重复触发分页加载请求
内容的提问来源于stack exchange,提问作者karthikeyan
相关产品推荐
相关产品推荐

