FlutterGen:通过Codegen实现资源的高效访问

在这里插入图片描述
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支持xmltype="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,
  ),

猜你喜欢

转载自blog.csdn.net/vitaviva/article/details/108672770