flutter assets
加载 assets
应用可以通过AssetBundle访问assets
有两种方法可以加载字符串或者图片,只需要在pubspec.yaml
中指定这些资源的路径即可
加载文本
每个程序中都会有一个rootBunlde对象,可以很轻松的访问主资源包,可以直接使用package:flutter/services.dart
中全局静态rootBundle
对象来加载assets
但是建议使用DefaultAssetBundle来获取BuildContext
的AssetBundle
, 这种方法不是使用应用程序构建的默认asset bundle
,而是使父widget
在运行时替换的不同的AssetBundle
,这对于本地化或者测试很有用。
通常,可以使用DefaultAssetBundle.of()
从应用运行时的rootBundle
加载asset
(例如JSON
文件)。
在Widget
上下文之外,或AssetBundle
不可用时,可以使用rootBundle
直接加载这些asset
例如:
import 'dart:async' show Future;
import 'package:flutter/services.dart' show rootBundle;
Future<String> loadAsset() async {
return await rootBundle.loadString('assets/config.json');
}
加载图片
声明图片
flutter
可以根据当前设备的像素加载不同分辨率的图片,AssetImage了解怎么根据设备的像素加载不同的图片,只需要在pubspec.yaml
中指定不同分辨率的图片即可
.../image.png
.../Mx/image.png
.../Nx/image.png
...etc.
M和N是数字标识符,类似于iOS中的那样,
假如主要的资源对应1.0分辨率的设备,那么考虑用以下命名方式指定assets
.../my_icon.png
.../2.0x/my_icon.png
.../3.0x/my_icon.png
在设备像素比例为1.8
的设备上,会选择2.0x
下的文件,对于2.7
的比例设备上则会选择3.0x
下的问题件
如果没有在Image
控件中指定图片的宽高,则使用默认分辨率来缩放资源,以便和主要资源占用相同的大小,只不过分辨率会更好,也就是说,如果.../my_icon.png
是72px
乘72px
,那么.../3.0x/my_icon.png
应该是216px
乘216px
, 但是如果未指定宽高,它们都将渲染为72
像素×72
像素(以逻辑像素为单位)
pubspec.yaml
中asset
部分的每一项都应该与实际文件相对应,但主资源项除外,当主资源缺少某个资源时,会按分辨率从低到高的顺序去选择
加载图片
如果要加载图片,请在widget
的build
方法中使用AssetImage
如果使用默认的assets bundle
加载资源时,内部会自动处理分辨率,如果使用更低级别的类,例如ImageStream和ImageCache,你还会注意到与缩放有关的参数
Container(
child: Image(
image: AssetImage('assets/images/food02.jpeg'),
height: 300.0,
width: 300.0,
),
)
和平台共享assets
通过Android
上的AssetManager
和iOS
上的NSBundle
,平台代码也随时可以使用Flutter
资源。
android
android
上可以通过AssetManager获取asset
, 例如使用openFd 根据key
查找。
key
可以使用PluginRegistry.Registrar的lookupKeyForAsset
和FlutterView的getLookupKeyForAsset
获得, PluginRegistry.Registrar
在开发插件的时候非常适用,而FlutterView
则在开发包括平台view
的app
时非常适用
示例:
flutter:
assets:
- icons/heart.png
项目目录:
.../pubspec.yaml
.../icons/heart.png
...etc.
如果想在插件中访问heart.png
,则可以
AssetManager assetManager = registrar.context().getAssets();
String key = registrar.lookupKeyForAsset("icons/heart.png");
AssetFileDescriptor fd = assetManager.openFd(key);
ios
在ios
中,assets
可以使用mainbundle获取, 例如使用 pathForResource:ofType: 根据key
查找。
key
可以使用FlutterPluginRegistrar的lookupKeyForAsset
和lookupKeyForAsset:fromPackage:
, 或者FlutterViewController的lookupKeyForAsset
和lookupKeyForAsset:fromPackage:
FlutterPluginRegistrar
在开发插件的时候非常适用,而FlutterViewController
则在开发包括平台view
的app
时非常适用
和android
示例相同,ios
获取则可以
NSString* key = [registrar lookupKeyForAsset:@"icons/heart.png"];
NSString* path = [[NSBundle mainBundle] pathForResource:key ofType:nil];
更完整的示例,请查看Flutter video_payer插件的实现。
使用平台资源
有时候可以直接在平台项目中使用asset
。以下是在Flutter
框架加载并运行之前使用资源的两种常见情况
更新app图标
android
导航到.../android/app/src/main/res
目录,mipmap-
开头的各种文件夹放置的就是不同分辨率的图标,如果想替换,根据Android开发人员指南 替换相应的图片即可
注:
如果想重命名图标,记得要在AndroidManifest.xml
的application
标签中替换修改后的名称
ios
导航到.../ios/Runner
,该目录中的Assets.xcassets/AppIcon.appiconset
已经包含了占位符图片,只需要根据ios开发人员指南 将它们替换为适当大小的图像即可,
更新启动页
在flutter
加载时,flutter
也使用本地平台机制将过渡启动屏幕绘制到flutter
应用程序,此启动屏幕将持续到flutter
渲染应用程序的第一帧
也就意味着只要不调用void main()
,屏幕将会一直显示启动页
android
导航到.../android/app/src/main
,在res/drawable/launch_background.xml
中已经有一个示例,根据示例可以自定义启动页
使用者可以通过LayerList自定义启动页,也可以使用其他drawable
ios
导航至.../ios/Runner
,在Assets.xcassets/LaunchImage.imageset
,替换LaunchImage.png
,LaunchImage@2x.png
,LaunchImage@3x.png
即可,如果要修改名字,则要更新Contents.json
也可以通过xcode
自定义启动页