Flutter如何基于设备像素密度加载适配的ui.Image资源
实现方案
你可以通过监听AssetImage(属于ImageProvider类型)的图片加载流来获取带分辨率感知的ui.Image实例,完整实现如下:
核心实现代码
import 'dart:async'; import 'dart:ui' as ui; import 'package:flutter/widgets.dart'; Future<ui.Image> loadAssetImage(String assetPath, BuildContext context) async { final ImageProvider imageProvider = AssetImage(assetPath); // 基于当前上下文生成本地图片配置,自动携带当前设备的像素密度信息 final ImageConfiguration config = createLocalImageConfiguration(context); final Completer<ui.Image> completer = Completer<ui.Image>(); void imageListener(ImageInfo info, bool syncCall) { completer.complete(info.image); } final ImageStream stream = imageProvider.resolve(config); stream.addListener(ImageStreamListener(imageListener)); // 加载完成后移除监听器避免内存泄漏 final ui.Image result = await completer.future; stream.removeListener(ImageStreamListener(imageListener)); return result; }
使用说明
- 调用时传入资源路径和当前页面的BuildContext即可,例:
loadAssetImage('assets/some_image.jpg', context) - 该实现会自动根据设备像素密度匹配对应倍率目录下的资源,你只需要按Flutter官方规范把不同分辨率的图片放到1.5x/2x/3x等目录下,无需额外调整代码
- 拿到
ui.Image使用完成后务必调用dispose()方法释放内存,避免内存泄漏 - 确保你已经在
pubspec.yaml中正确声明了根路径下的资源,无需单独声明各个倍率目录下的文件,示例配置:
flutter: assets: - assets/some_image.jpg
无Context的替代实现
如果你拿不到当前上下文,也可以手动指定像素密度构造配置:
Future<ui.Image> loadAssetImageWithoutContext(String assetPath) async { final ImageProvider imageProvider = AssetImage(assetPath); // 直接获取全局设备像素密度 final double pixelRatio = WidgetsBinding.instance.platformDispatcher.views.first.devicePixelRatio; final ImageConfiguration config = ImageConfiguration(devicePixelRatio: pixelRatio); // 后续逻辑和上面的实现完全一致 final Completer<ui.Image> completer = Completer<ui.Image>(); void imageListener(ImageInfo info, bool syncCall) { completer.complete(info.image); } final ImageStream stream = imageProvider.resolve(config); stream.addListener(ImageStreamListener(imageListener)); final ui.Image result = await completer.future; stream.removeListener(ImageStreamListener(imageListener)); return result; }
内容的提问来源于stack exchange,提问作者user12441223
相关产品推荐
相关产品推荐

