import 'package:flutter/services.dart' show rootBundle;
Future<String> loadAsset() async {
return await rootBundle.loadString('assets/config.json');
你可以在 build()
方法中使用 AssetImage
加载图片。
举个例子,下面的代码加载了先前声明的背景图片:
dartreturn const Image(image: AssetImage('assets/background.png'));
分辨率自适应图片资源
Flutter 可以为当前设备加载适合其
设备像素比 的图像。
AssetImage
可以将请求资源映射到最接近当前
设备像素比 的资源。
为了使这种映射起作用,资源应该根据特定的目录结构来保存:
.../image.png
.../Mx/image.png
.../Nx/image.png
...etc.
其中 M 和 N 是数字标识符,对应于其中包含的图像的分辨率,换句话说,它们指定不同设备像素比例的图片。
在示例中,image.png
是 主资源,而 Mx/image.png
和 Nx/image.png
则被认为是 变体。
主资源默认对应于 1.0 倍的分辨率图片。比如下面的图片 my_icon.png
:
.../my_icon.png (mdpi baseline)
.../1.5x/my_icon.png (hdpi)
.../2.0x/my_icon.png (xhdpi)
.../3.0x/my_icon.png (xxhdpi)
.../4.0x/my_icon.png (xxxhdpi)
而在设备像素比率为 1.8 的设备上,对应是 .../2.0x/my_icon.png
。如果是 2.7 的设备像素比,对应是 .../3.0x/my_icon.png
。
如果在 Image
widget 上未指定渲染图像的宽度和高度,通常会扩展资源来保证与主资源相同的屏幕空间量,并不是相同的物理像素,只是分辨率更高。换句话说,.../my_icon.png
是 72 px 乘 72 px,那么 .../3.0x/my_icon.png
应该是 216 px 乘 216 px;但如果未指定宽度和高度,它们都将渲染为 72 px 乘 72 px(以逻辑像素为单位)。
设备像素比 依赖于 MediaQueryData.size,它们需要你的 AssetImage
的上层节点中存在 MaterialApp 或者 CupertinoApp。
Bundling of resolution-aware image assets
你只需要在 pubspec.yaml
的 assets
部分指定主要资源,
Flutter 会自动帮你绑定其他变体。在 pubspec.yaml
中资源部分的每一项都应与实际文件相对应,除过主资源节点。当主资源缺少某个文件时,会按分辨率从低到高的顺序去选择,也就是说 1x 中没有的话会在 2x 中找,2x 中还没有的话就在 3x 中找。该条目需要在 pubspec.yaml
中指定。
使用默认的资源 bundle 加载资源时,系统会自动处理分辨率等。(如果你使用一些更低级别的类,如 ImageStream
或
ImageCache
,你需要注意 scale 相关的参数)。
依赖包中的资源图片
加载依赖 package 中的图像,必须给 AssetImage
提供 package
参数。
例如,你的应用程序依赖于一个名为 my_icons
的 package,它的目录结构如下:
.../pubspec.yaml
.../icons/heart.png
.../icons/1.5x/heart.png
.../icons/2.0x/heart.png
...etc.
然后加载 image, 使用:
dartreturn const AssetImage('icons/heart.png', package: 'my_icons');
package 使用本身的 Assets 也需要加上 package
参数来获取。
打包 assets
如果期望的资源文件被指定在 package 的 pubspec.yaml
文件中,它会被自动打包到应用程序中。特别是,package 本身使用的资源必须在 pubspec.yaml
中指定。
package 也可以选择在其 lib/
文件夹中包含未在 pubspec.yaml
文件中声明的资源。在这种情况下,对于要打包的图片,应用程序必须在 pubspec.yaml
中指定包含哪些图像。例如,一个名为 fancy_backgrounds
的包,可能包含以下文件:
.../lib/backgrounds/background1.png
.../lib/backgrounds/background2.png
.../lib/backgrounds/background3.png
总而言之,要包含第一张图像,必须在 pubspec.yaml
的 assets
部分中声明它:
yamlflutter:
assets:
- packages/fancy_backgrounds/backgrounds/background1.png
lib/
是隐含的,所以它不应该包含在资源路径中。
如果你正在开发 package,想要从 package 中加载资源,首先要在 pubspec.yaml
中定义:
yamlflutter:
assets:
- assets/images/
在 package 中加载图片,按以下方式:
dartreturn const AssetImage('packages/fancy_backgrounds/backgrounds/background1.png');
在不同平台读取 Flutter assets,
Android 是通过 AssetManager
,iOS 是 NSBundle
。
在 Android 中加载 Flutter 资源文件
在 Android 平台上,assets 通过 AssetManager
API 读取。通过 PluginRegistry.Registrar
的 lookupKeyForAsset
方法,或者 FlutterView
的 getLookupKeyForAsset
方法来获取文件路径,然后 AssetManager
的 openFd
根据文件路径得到文件描述符。开发插件时可以使用 PluginRegistry.Registrar
,而开发应用程序使用平台视图时,FlutterView
是最好的选择。
举个例子,假设你在 pubspec.yaml 中这样指定:
yamlflutter:
assets:
- icons/heart.png
在你的 Flutter 应用程序对应以下结构。
.../pubspec.yaml
.../icons/heart.png
...etc.
想要在 Java 插件中访问 icons/heart.png
;
javaAssetManager assetManager = registrar.context().getAssets();
String key = registrar.lookupKeyForAsset("icons/heart.png");
AssetFileDescriptor fd = assetManager.openFd(key);
在 iOS 中加载 Flutter 资源文件
在 iOS 平台上,assets 资源文件通过 mainBundle
读取。通过 pathForResource:ofType:
的 lookupKeyForAsset
或者 lookupKeyForAsset:fromPackage:
方法获取文件路径,同样,FlutterViewController
的 lookupKeyForAsset:
或者 lookupKeyForAsset:fromPackage:
方法也可以获取文件路径。开发插件时可以使用 FlutterPluginRegistrar
,而开发应用程序使用平台视图时, FlutterViewController
是最好的选择。
举个例子,假设你的 Flutter 配置和上面一样。
要在 Objective-C 插件中访问 icons/heart.png
:
objcNSString* key = [registrar lookupKeyForAsset:@"icons/heart.png"];
NSString* path = [[NSBundle mainBundle] pathForResource:key ofType:nil];
要在 Swift 应用程序中访问 icons/heart.png
:
swiftlet key = controller.lookupKey(forAsset: "icons/heart.png")
let mainBundle = Bundle.main
let path = mainBundle.path(forResource: key, ofType: nil)
这有一个更完整的实例可以理解 Flutter 的应用:
video_player
plugin。
pub.dev 上的 ios_platform_images
plugin 将这些逻辑封装成方便的类别。它允许编写:
Objective-C:
objc[UIImage flutterImageWithName:@"icons/heart.png"];
Swift:
swiftUIImage.flutterImageNamed("icons/heart.png")
在 Flutter 中加载 iOS 的图片
当你在 iOS 应用程序中添加 Flutter 时,你可能希望在 Flutter 中使用 iOS 中的图片。为了实现这一点,可以使用 pub.dev 上的 ios_platform_images
插件。
某些场景可以直接在平台项目中使用 assets。以下是在 Flutter 框架加载并运行之前使用资源的两种常见情况。
更新桌面图标
更新你的 Flutter 应用程序启动图标,和原生 Android 或 iOS 应用程序中更新启动图标的方法相同。
Android
在 Flutter 项目的根目录中,导航到 .../android/app/src/main/res
路径。各种位图资源文件夹,比如 mipmap-hdpi
,已包含占位符图像 ic_launcher.png
。只需按照 Android 开发者指南 中的说明,将其替换为所需的资源,并遵守每种屏幕分辨率的建议图标大小标准。
Android
将启动屏幕「splash screen」添加到你的 Flutter 应用程序,请导航至 .../android/app/src/main
路径。在 res/drawable/launch_background.xml
文件中,通过使用
图层列表 XML 来实现自定义启动页。现有模板提供了一个示例,用于将图片添加到白色启动页的中间(注释代码中)。你也可以取消注释使用 可绘制对象资源 来实现预期效果。
更多详细信息,请查看
在 Android 应用中添加闪屏页与启动页。
将图片添加到启动屏幕「splash screen」的中心,请导航至 .../ios/Runner
路径。在 Assets.xcassets/LaunchImage.imageset
,拖入图片,并命名为 LaunchImage.png
, [email protected]
,[email protected]
。如果你使用不同的文件名,那你还必须更新同一目录中的 Contents.json
文件中对应的名称。
你也可以通过打开 .../ios/Runner.xcworkspace
,完全自定义 storyboard。在 Project Navigator 中导航到 Runner/Runner
,然后打开 Assets.xcassets
拖入图片,或者在 LaunchScreen.storyboard
中使用 Interface Builder 进行自定义。
更多详细信息,请查看
在 iOS 应用中添加闪屏页与启动页。
除非另有说明,本文档之所提及适用于 Flutter 的最新稳定版本,本页面最后更新时间: 2024-11-02。
查看文档源码
为本页面内容提出建议。