添加资源和图像
Flutter 应用可以包含代码和资源(有时称为资源)。资源是指与您的应用捆绑并部署的文件,并在运行时可访问。常见的资源类型包括静态数据(例如,JSON 文件)、配置文件、图标和图像(JPEG、WebP、GIF、动画 WebP/GIF、PNG、BMP 和 WBMP)。
指定资源
#Flutter 使用位于项目根目录的pubspec.yaml
文件来识别应用所需的资源。
这是一个示例
flutter:
assets:
- assets/my_icon.png
- assets/background.png
要包含某个目录下的所有资源,请在目录名称后指定/
字符
flutter:
assets:
- directory/
- directory/subdirectory/
资源捆绑
#flutter
部分的assets
子部分指定应与应用一起包含的文件。每个资源都由一个显式路径(相对于pubspec.yaml
文件)标识,其中包含资源文件的位置。声明资源的顺序无关紧要。使用的实际目录名称(第一个示例中的assets
或上述示例中的directory
)无关紧要。
在构建期间,Flutter 将资源放入一个称为资源包的特殊存档中,应用在运行时从中读取。
构建时自动转换资源文件
#Flutter 支持使用 Dart 包在构建应用时转换资源文件。为此,请在您的 pubspec 文件中指定资源文件和转换器包。要了解如何执行此操作并编写您自己的资源转换包,请参阅构建时转换资源。
基于应用风味的条件性资源捆绑
#如果您的项目利用了风味功能,您可以配置仅在应用的某些风味中捆绑各个资源。有关更多信息,请查看基于风味有条件地捆绑资源。
加载资源
#您的应用可以通过AssetBundle
对象访问其资源。
资源包上的两种主要方法允许您从包中加载字符串/文本资源(loadString()
)或图像/二进制资源(load()
),给定一个逻辑键。逻辑键映射到构建时在pubspec.yaml
文件中指定的资源路径。
加载文本资源
#每个 Flutter 应用都有一个rootBundle
对象,以便轻松访问主资源包。可以使用来自package:flutter/services.dart
的rootBundle
全局静态直接加载资源。
但是,建议使用DefaultAssetBundle
获取当前BuildContext
的AssetBundle
,而不是与应用一起构建的默认资源包;这种方法使父部件能够在运行时替换不同的AssetBundle
,这对于本地化或测试场景非常有用。
通常,您将使用DefaultAssetBundle.of()
间接加载资源,例如来自应用运行时rootBundle
的 JSON 文件。
在Widget
上下文之外,或者当AssetBundle
的句柄不可用时,您可以使用rootBundle
直接加载此类资源。例如
import 'package:flutter/services.dart' show rootBundle;
Future<String> loadAsset() async {
return await rootBundle.loadString('assets/config.json');
}
加载图像
#要加载图像,请在部件的build()
方法中使用AssetImage
类。
例如,您的应用可以从先前示例中的资源声明中加载背景图像
return 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
部件上指定渲染图像的宽度和高度,则使用名义分辨率缩放资源,使其占据与主资源相同的屏幕空间,只是分辨率更高。也就是说,如果.../my_icon.png
为 72px x 72px,则.../3.0x/my_icon.png
应为 216px x 216px;但如果未指定宽度和高度,则它们都渲染成 72px x 72px(以逻辑像素为单位)。
分辨率感知图像资源的捆绑
#您只需要在pubspec.yaml
的assets
部分中指定主资源或其父目录。Flutter 会为您捆绑变体。每个条目都应对应一个真实文件,主资源条目除外。如果主资源条目不对应于真实文件,则使用最低分辨率的资源作为设备像素比低于该分辨率的设备的回退。但是,该条目仍应包含在pubspec.yaml
清单中。
使用默认资源包的任何内容在加载图像时都继承分辨率感知功能。(如果您使用某些较低级别的类,例如ImageStream
或ImageCache
,您还会注意到与缩放相关的参数。)
包依赖项中的资源图像
#要从包依赖项加载图像,必须将package
参数提供给AssetImage
。
例如,假设您的应用程序依赖于名为my_icons
的包,该包具有以下目录结构
.../pubspec.yaml
.../icons/heart.png
.../icons/1.5x/heart.png
.../icons/2.0x/heart.png
...etc.
要加载图像,请使用
return const AssetImage('icons/heart.png', package: 'my_icons');
包本身使用的资源也应使用上述package
参数获取。
包资源的捆绑
#如果所需的资源在包的pubspec.yaml
文件中指定,则会将其自动与应用程序捆绑在一起。特别是,包本身使用的资源必须在其pubspec.yaml
中指定。
包也可以选择在其lib/
文件夹中包含未在其pubspec.yaml
文件中指定的资源。在这种情况下,为了将这些图像捆绑在一起,应用程序必须指定要包含哪些图像。例如,名为fancy_backgrounds
的包可能具有以下文件
.../lib/backgrounds/background1.png
.../lib/backgrounds/background2.png
.../lib/backgrounds/background3.png
例如,要包含第一个图像,应用程序的pubspec.yaml
应在assets
部分中指定它
flutter:
assets:
- packages/fancy_backgrounds/backgrounds/background1.png
lib/
是隐含的,因此不应包含在资源路径中。
如果您正在开发包,要加载包内的资源,请在包的pubspec.yaml
中指定它
flutter:
assets:
- assets/images/
要在包中加载图像,请使用
return const AssetImage('packages/fancy_backgrounds/backgrounds/background1.png');
与底层平台共享资源
#Flutter 资源可通过 Android 上的AssetManager
和 iOS 上的NSBundle
轻松提供给平台代码。
在 Android 中加载 Flutter 资源
#在 Android 上,可以通过AssetManager
API 访问资源。例如,在openFd
中使用的查找键是从PluginRegistry.Registrar
上的lookupKeyForAsset
或FlutterView
上的getLookupKeyForAsset
获取的。在开发插件时可以使用PluginRegistry.Registrar
,而在开发包含平台视图的应用时,FlutterView
将是首选。
例如,假设您在 pubspec.yaml 中指定了以下内容
flutter:
assets:
- icons/heart.png
这反映了 Flutter 应用中的以下结构。
.../pubspec.yaml
.../icons/heart.png
...etc.
要从您的 Java 插件代码访问icons/heart.png
,请执行以下操作
AssetManager assetManager = registrar.context().getAssets();
String key = registrar.lookupKeyForAsset("icons/heart.png");
AssetFileDescriptor fd = assetManager.openFd(key);
在 iOS 中加载 Flutter 资源
#在 iOS 上,可以通过mainBundle
访问资源。例如,在pathForResource:ofType:
中使用的查找键是从FlutterPluginRegistrar
上的lookupKeyForAsset
或lookupKeyForAsset:fromPackage:
,或FlutterViewController
上的lookupKeyForAsset:
或lookupKeyForAsset:fromPackage:
获取的。在开发插件时可以使用FlutterPluginRegistrar
,而在开发包含平台视图的应用时,FlutterViewController
将是首选。
例如,假设您具有上述 Flutter 设置。
要从您的 Objective-C 插件代码访问icons/heart.png
,您将执行以下操作
NSString* key = [registrar lookupKeyForAsset:@"icons/heart.png"];
NSString* path = [[NSBundle mainBundle] pathForResource:key ofType:nil];
要从您的 Swift 应用访问icons/heart.png
,您将执行以下操作
let key = controller.lookupKey(forAsset: "icons/heart.png")
let mainBundle = Bundle.main
let path = mainBundle.path(forResource: key, ofType: nil)
有关更完整的示例,请参阅 pub.dev 上 Flutter video_player
插件的实现。
pub.dev 上的ios_platform_images
插件将此逻辑封装在一个方便的类别中。您可以按如下方式获取图像
Objective-C
[UIImage flutterImageWithName:@"icons/heart.png"];
Swift
UIImage.flutterImageNamed("icons/heart.png")
在 Flutter 中加载 iOS 图像
#在通过将其添加到现有的 iOS 应用来实现 Flutter 时,您可能在 iOS 中托管了要在 Flutter 中使用的图像。为此,请使用 pub.dev 上提供的ios_platform_images
插件。
平台资源
#在平台项目中直接处理资源还有其他情况。以下是 Flutter 框架加载并运行之前使用资源的两种常见情况。
更新应用图标
#更新 Flutter 应用程序的启动图标与更新原生 Android 或 iOS 应用程序的启动图标的方式相同。
Android
#在 Flutter 项目的根目录中,导航到 .../android/app/src/main/res
。各种位图资源文件夹(如 mipmap-hdpi
)已经包含名为 ic_launcher.png
的占位符图像。用您所需的资源替换它们,并根据屏幕密度遵循推荐的图标大小,如 Android 开发者指南 中所述。
iOS
#在 Flutter 项目的根目录中,导航到 .../ios/Runner
。Assets.xcassets/AppIcon.appiconset
目录已包含占位符图像。用适当大小的图像替换它们,这些图像的大小由文件名决定,如 Apple 的 人机界面指南 中所述。保留原始文件名。
更新启动画面
#Flutter 还使用原生平台机制为您的 Flutter 应用程序绘制过渡启动屏幕,同时 Flutter 框架加载。此启动屏幕会一直存在,直到 Flutter 呈现应用程序的第一帧。
Android
#要向 Flutter 应用程序添加启动屏幕(也称为“启动画面”),请导航到 .../android/app/src/main
。在 res/drawable/launch_background.xml
中,使用此 图层列表可绘制对象 XML 自定义启动屏幕的外观。现有模板提供了一个示例,说明如何在注释代码中将图像添加到白色启动屏幕的中间。您可以取消注释它或使用其他 可绘制对象 来实现预期的效果。
有关更多详细信息,请参阅 向 Android 应用添加启动画面。
iOS
#要将图像添加到“启动画面”的中心,请导航到 .../ios/Runner
。在 Assets.xcassets/LaunchImage.imageset
中,放入名为 LaunchImage.png
、[email protected]
、[email protected]
的图像。如果您使用不同的文件名,请更新同一目录中的 Contents.json
文件。
您还可以通过在 Xcode 中打开 .../ios/Runner.xcworkspace
来完全自定义启动屏幕故事板。在项目导航器中导航到 Runner/Runner
,并通过打开 Assets.xcassets
放入图像,或使用 LaunchScreen.storyboard
中的界面生成器进行任何自定义。
有关更多详细信息,请参阅 向 iOS 应用添加启动画面。
除非另有说明,否则本网站上的文档反映了 Flutter 的最新稳定版本。页面上次更新于 2024-09-04。 查看源代码 或 报告问题.