https://flutter.io/assets-and-images/
介绍:
Flutter app需要有代码与assets,assets是文件,部署在app里面的,在运行时可以访问,通常的assets包含,数据,配置文件,图标,图片.
指定assets
Flutter使用pubspec.yaml文件,定位项目的根,以定位assets.
示例:
flutter:
assets:
- assets/my_icon.png
- assets/background.png
要包含所有的assets东西,可以简化一下
flutter:
assets:
- assets/
只在这个目录里的文件会被包含进来,如果是子目录需要添加引用.
assets 绑定
assets,指定了在Flutter app包含的文件.每一个assets 以路径标识.(相对于pubspec.yaml),顺序不重要.真实目录也不重要.
构建过程,Flutter会把这些打包进assets的bundle,这些可以运行时访问的.
assets 变体
构建过程,支持assets 变体,一个assets 的不同版本会在不同的上下文展示,当一个assets 在yaml里配置了.构建进程会查找邻近目录所有相同名字文件.
如,目录下有以下文件:
.../pubspec.yaml
.../graphics/my_icon.png
.../graphics/background.png
.../graphics/dark/background.png
...etc.
你的文件包含
flutter:
assets:
- graphics/background.png
graphics/background.png
and graphics/dark/background.png
会同时被引进的.普通的是认为主assets,另一个是变体
也可以在yaml里使用目录来指定
flutter:
assets:
- graphics/
这样graphics/my_icon.png
, graphics/background.png
and graphics/dark/background.png就全部包含进来了.
Flutter在不同分辨率适配时使用变体.这种机制可以扩展到语言环境等情况.
加载Assets
使用AssetBundle对象来访问assets
两个主要的方法允许你加载字符,文件的assets,loadString()或图片load().需要一个逻辑key,逻辑key在构建时映射到路径上.
加载文本的assets
每一个Flutter app有一个rootBundle对象,可以很容易地访问assets.可以通过全局静态导入的来加载.package:flutter/services.dart
.
然而,还是建议使用AssetBundle,传入当前的BuildContext来加载.这种方式,会让父控件,去适配不同的assetbundle,可以本地化.可测试.
通常,使用DefaultAssetBundle.of()直接加载.
在控件上下文外,要处理AssetBundle是不可行的时候,可以使用rootBundle来加载.
import 'dart:async' show Future;
import 'package:flutter/services.dart' show rootBundle;
Future<String> loadAsset() async {
return await rootBundle.loadString('assets/config.json');
}
加载图片:
Flutter可以处理不同分辨率的图片.
定义不同分辨率的图片assets
AssetImage知道如何去映射一个请求,以适配当前的分辨率.要处理这种映射,asset需要按特定的目录去组织文件:
.../image.png
.../Mx/image.png
.../Nx/image.png
...etc.
这点与Android是类似的.xhdpi/xxhdpi等.
M/N表示分辨率值,换句话说,他们指定了设备的缩放率.
主asset默认是1.0,如my_icon.png:
.../my_icon.png
.../2.0x/my_icon.png
.../3.0x/my_icon.png
像素缩放比是1.8的设备上,2.0x/my_icon.png会被选中,2.7的会对应3.0x的图片.
如果Image的高宽不指定,默认的分辨率会使用缩放来适应.如果高宽未指定,3x与1x的图片都会在1x的高宽上渲染的.
pubspec.yaml里的每一个入口都需要对应真实的文件.否则会有异常.如果主asset入口不映射到一个真实文件,低分辨率的会被使用.
加载图片:
要加载图片,使用AssetImage类.在控件的build方法里
如添加背景图
Widget build(BuildContext context) {
// ...
return DecoratedBox(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('graphics/background.png'),
// ...
),
// ...
),
);
// ...
}
继承默认的asset bundle会继承分辨率.
添加图片到包依赖:
从依赖包中加载图片,包参数需要提供给AssetImage.假如你的app依赖my_icons包,它的目录是:
.../pubspec.yaml
.../icons/heart.png
.../icons/1.5x/heart.png
.../icons/2.0x/heart.png
...etc.
加载时:
AssetImage('icons/heart.png', package: 'my_icons')
该包加载时,也要带包参数
绑定包assets
在yaml里指定的,会自动打包进来的.app使用的都要在yaml里指定.
一个包,也可以选择放在lib目录中,不在yaml里指定.如在fancy_backgrounds
包下的文件:
.../lib/backgrounds/background1.png
.../lib/backgrounds/background2.png
.../lib/backgrounds/background3.png
要引用第一张图片,也要指定它:
flutter:
assets:
- packages/fancy_backgrounds/backgrounds/background1.png
lib/目录不需要再包含,它是隐式地.
不同平台共享资源:
Flutter的assets可以通过不同平台的AssetManager来管理.
Android
可以使用AssetManager来管理.FlutterView的lookupKeyForAsset
on PluginRegistry.Registrar or getLookupKeyForAsset
可以实现查找.PluginRegistry.Registrar在开发插件时,选用.
假设你在yaml里这么写:
flutter:
assets:
- icons/heart.png
在你app里的结构:
.../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
mainBundle可以访问它.pathForResource:ofType: 类型的key也是通过FlutterViewController的lookupKeyForAsset
or lookupKeyForAsset:fromPackage:
on FlutterPluginRegistrar or lookupKeyForAsset:
or lookupKeyForAsset:fromPackage来查找.
要访问heart.png:
NSString* key = [registrar lookupKeyForAsset:@"icons/heart.png"];
NSString* path = [[NSBundle mainBundle] pathForResource:key ofType:nil];
更复杂的示例可以查看video_payer plugin.
平台Assets
有些时候,可能要直接使用平台的assets.以下有两个示例:
更新应用图标
两端是一样的.
Android:
Flutter的根目录,导航到../android/app/src/main/res.包含ic_launcher.png的目录可以看到.如何替换,可以查看Android规范: Android Developer Guide
IOS
根节点导航到./ios/Runner,Assets.xcassets/AppIcon.appiconset下面就是图标了.通过 Human Interface Guidelines查看
Flutter会使用平台各自的机制来渲染启动屏幕.直接Flutter渲染第一帧.
Android,添加闪屏,到./android/app/src/main/res/drawable/launch_background.xml,可以使用layer list drawable来自定义闪屏.
ios,同样,在自己的目录里添加图片