Android通过aapt生成R.java,可以更加programmatically地访问res/下的各种资源,无需使用类似"res/drawable/logo.png"这样的hardcode,安全高效。
Flutter没有上述功能,所以只能通过pubspec.yaml定义的assets的字符串访问资源。今天推荐一个开源项目FlutterGen,可以像Android一样通过代码生成,安全高效的访问资源。
基本功能
现状,需要在pubspec.yaml
中定义
flutter:
assets:
- assets/images/profile.jpg
然后,通过字符串访问
Widget build(BuildContext context) {
return Image.asset('assets/images/profile.jpeg');
}
如果不小心写错了 ,例如上面讲jpg写成了jpeg,运行时异常:
The following assertion was thrown resolving an image codec:
Unable to load asset: assets/images/profile.jpeg
通过FlutterGen可以实现TypeSafe的资源访问
Widget build(BuildContext context) {
return Assets.images.profile.image();
}
安装
支持Homebrew、Dart Command-line 以及 build_runner 等三种安装方式
1. Homebrew
# 通过 Brew tap 安装 flutter_gen (macos, linux)
$ brew install FlutterGen/tap/fluttergen
# 确认安装成功
$ fluttergen -h
# 指定 pubspec.yaml 路径
# 默认使用 ./pubspec.yaml 作为路径
$ fluttergen -c example/pubspec.yaml
2. Dart Command-line
FlutterGen不依赖FlutterSDK,可以只基于Dart生成
# 从pub.dev 安装 flutter_gen
$ pub global activate flutter_gen
# 设置环境变量
$ export PATH="$PATH":"$HOME/.pub-cache/bin"
# 确认
$ fluttergen -h
# 指定 pubspec.yaml 路径
# 默认使用 ./pubspec.yaml 作为路径
$ fluttergen -c example/pubspec.yaml
3. build_runner
pubspec.yaml
中添加 build_runner 以及 flutter_gen
dev_dependencies:
build_runner:
flutter_gen:
下载并运行
# 获取依赖关系
$ flutter pub get
# 运行 build_runner
$ flutter packages pub run build_runner build
yaml配置
pubspec.yaml整体配置如下:
name: example
description: A sample project using FlutterGen.
publish_to: 'none'
version: 1.0.0+1
environment:
sdk: '>=2.9.0 <3.0.0'
flutter: '>=1.20.0'
dependencies:
flutter:
sdk: flutter
dev_dependencies:
flutter_test:
sdk: flutter
build_runner:
flutter_gen:
flutter_gen:
output: lib/gen/ # Optional (default: lib/gen/)
lineLength: 80 # Optional (default: 80)
integrations:
flutter_svg: true
colors:
inputs:
- assets/color/colors.xml
flutter:
uses-material-design: true
assets:
- assets/images/
fonts:
- family: Raleway
fonts:
- asset: assets/fonts/Raleway-Regular.ttf
- asset: assets/fonts/Raleway-Italic.ttf
style: italic
flutterGen中可以指定output也lineLength
- output:代码生成位置
- lineLength:生成代码的最大行长度
生成规则
1.图片
flutter:
assets:
- assets/images/
- assets/images/chip3/chip.jpg
- assets/images/chip4/chip.jpg
- assets/images/icons/paint.svg
- assets/json/fruits.json
- pictures/ocean_view.jpg
针对文件夹(例如assets/image/
)下的资源进行转换,例如:
assets/images/chip.png => Assets.images.chip
chip
作为AssetImage
class在代码中使用
Widget build(BuildContext context) {
return Image(image: Assets.images.chip);
}
Widget build(BuildContext context) {
return Assets.images.chip.image(
width: 120,
height: 120,
fit: BoxFit.scaleDown,
);
Widget build(BuildContext context) {
return Image.asset(Assets.images.chip.path);
}
当文件层级较多时:
assets/images/chip/chip.jpg => Assets.images.chip3.chip
assets/images/chip4/chip.jpg => Assets.images.chip4.chip
assets/json/fruits.json => Assets.json.fruits
assets/images/icons/paint.svg => Assets.images.icons.paint
pictures/ocean_view.jpg => Assets.pictures.oceanView
2.font
flutter:
fonts:
- family: Raleway
fonts:
- asset: assets/fonts/Raleway-Regular.ttf
- asset: assets/fonts/Raleway-Italic.ttf
style: italic
- family: RobotoMono
fonts:
- asset: assets/fonts/RobotoMono-Regular.ttf
- asset: assets/fonts/RobotoMono-Bold.ttf
weight: 700
Text(
'Hi there, I\'m FlutterGen',
style: TextStyle(
fontFamily: FontFamily.robotoMono,
fontFamilyFallback: const [FontFamily.raleway],
),
3. color
flutter_gen:
colors:
inputs:
- assets/color/colors.xml
- assets/color/colors2.xml
<color name="milk_tea">#F5CB84</color>
<color name="cinnamon_red" type="material">#FFCF2A2A</color>
<color name="black_50">#80000000</color>
codeGen支持xml
中type="material"
的指定
static const MaterialColor crimsonRed = MaterialColor(
0xFFCF2A2A,
<int, Color>{
50: Color(0xFFF9E5E5),
100: Color(0xFFF1BFBF),
200: Color(0xFFE79595),
300: Color(0xFFDD6A6A),
400: Color(0xFFD64A4A),
500: Color(0xFFCF2A2A),
600: Color(0xFFCA2525),
700: Color(0xFFC31F1F),
800: Color(0xFFBD1919),
900: Color(0xFFB20F0F),
},
);
使用;:
Text(
'Hi there, I\'m FlutterGen',
style: TextStyle(
color: ColorName.milkTea,
),