Flutter自动生成代码插件ds_flutter_gen_runner的使用
Flutter自动生成代码插件ds_flutter_gen_runner的使用
该插件用于为您的资源(如资产、字体、颜色等)生成Dart代码,从而消除所有基于字符串的API。
注意:这是flutter_gen的一个分支。优先使用原版。
灵感来源于SwiftGen。
动机
直接使用资源路径字符串并不安全。
# pubspec.yaml
flutter:
assets:
- assets/images/profile.jpg
❌ 坏 如果拼写错误会发生什么?
Widget build(BuildContext context) {
return Image.asset('assets/images/profile.jpeg');
}
// 抛出异常:
// 无法加载资源:assets/images/profile.jpeg
⭕️ 好 我们希望安全地使用它们。
Widget build(BuildContext context) {
return Assets.images.profile.image();
}
安装过程
Homebrew
适用于macOS和Linux。
brew install FlutterGen/tap/fluttergen
asdf
适用于macOS和Linux。 asdf-fluttergen与mise兼容。
# 添加插件
asdf plugin add fluttergen
# 或
asdf plugin add fluttergen https://github.com/FlutterGen/asdf-fluttergen.git
# 安装fluttergen
asdf install fluttergen latest
Pub Global
适用于macOS、Linux和Windows。
dart pub global activate ds_flutter_gen
可能需要设置路径。
作为build_runner的一部分
- 在项目的
pubspec.yaml
文件中添加build_runner
和ds_flutter_gen_runner
依赖:
dev_dependencies:
build_runner:
ds_flutter_gen_runner:
- 安装
flutter_gen
flutter pub get
- 使用
flutter_gen
dart run build_runner build
GitHub Actions
适用于macOS和Linux。
- uses: FlutterGen/setup-fluttergen@v1
with:
version: ${{ fluttergen_version }}
参见:FlutterGen/setup-fluttergen
使用方法
在配置了pubspec.yaml
之后运行fluttergen
命令。
fluttergen -h
fluttergen -c example/pubspec.yaml
配置文件
ds_flutter_gen
根据pubspec.yaml
中的flutter
和ds_flutter_gen
键生成Dart文件。
默认配置可以在这里找到:这里。
# pubspec.yaml
# ...
ds_flutter_gen:
output: lib/gen/ # 可选,默认为lib/gen/
line_length: 80 # 可选,默认为80
# 可选
integrations:
flutter_svg: true
flare_flutter: true
rive: true
lottie: true
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
build.yaml
你也可以在build.yaml
中配置生成选项,它会在读取pubspec.yaml
之前被读取。
# build.yaml
# ...
targets:
$default:
builders:
ds_flutter_gen_runner: # 或者 flutter_gen
options:
output: lib/build_gen/ # 可选,默认为lib/gen/
line_length: 120 # 可选,默认为80
可用解析器
资源
遵循文档
添加资源和图片#指定资源
来指定资源,然后ds_flutter_gen
将生成相关的Dart文件。
无需其他特定配置。
# pubspec.yaml
flutter:
assets:
- assets/images/
- assets/images/chip3/chip.jpg
- assets/images/chip4/chip.jpg
- assets/images/icons/paint.svg
- assets/images/icons/dart@test.svg
- assets/json/fruits.json
- assets/flare/Penguin.flr
- assets/rive/vehicles.riv
- pictures/ocean_view.jpg
这些配置将在默认情况下在lib/gen/
目录下生成assets.gen.dart
文件。
带口味的资源
Flutter支持
基于口味有条件地捆绑资源。
仅在指定了口味时,资源才可用。
ds_flutter_gen
将生成指定的flavors
,无论当前的口味是什么。
可以通过.flavors
访问flavors
字段,例如:
print(MyAssets.images.chip4.flavors); // -> {'extern'}
排除生成特定资源
你可以使用Glob
模式指定ds_flutter_gen > assets > exclude
以排除特定资源。
ds_flutter_gen:
assets:
exclude:
- folder-your-want-to-exclude/**
- specified-asset.jpg
更多模式可以查看package:glob
。
为包生成资源
如果你想要为一个包生成资源,
可以在ds_flutter_gen > assets > outputs
下使用package_parameter_enabled
。
ds_flutter_gen:
assets:
outputs:
package_parameter_enabled: true # <- 添加此行。
这会向生成的类添加包常量。例如:
class Assets {
Assets._();
static const String package = 'test';
static const $AssetsImagesGen images = $AssetsImagesGen();
static const $AssetsUnknownGen unknown = $AssetsUnknownGen();
}
然后你可以隐式或显式地使用包中的资源:
// 隐式使用 `Image`/`SvgPicture`/`Lottie`。
Widget build(BuildContext context) {
return Assets.images.icons.paint.svg(
width: 120,
height: 120,
);
}
或者
// 显式使用 `Image`/`SvgPicture`/`Lottie`。
Widget build(BuildContext context) {
return SvgPicture.asset(
Assets.images.icons.paint.path,
package: Assets.package,
width: 120,
height: 120,
);
}
生成目录路径
如果你想生成目录路径,
可以在ds_flutter_gen > assets > outputs
下使用directory_path_enabled
。
ds_flutter_gen:
assets:
outputs:
directory_path_enabled: true # <- 添加此行。
这会向生成的目录类添加path
获取器。例如:
class $AssetsImagesGen {
const $AssetsImagesGen();
///******
/// 目录路径:assets/images
String get path => 'assets/images';
}
包含额外元数据
在构建时,可以通过使用parse_metadata
选项包含生成类中的额外元数据。
ds_flutter_gen:
parse_metadata: true # <- 添加此行(默认为false)
对于基于图像的资源,将在生成的类中添加新的可空size
字段。例如:
AssetGenImage get logo =>
const AssetGenImage('assets/images/logo.png', size: Size(209.0, 49.0));
现在可以在运行时不从实际资源中解析信息。
Widget build(BuildContext context) {
return Assets.images.logo.size!.width;
}
使用示例
ds_flutter_gen
会为Flutter支持的图像格式生成Image
类。
assets/images/chip.jpg
的结果示例:
<strong>Assets.images.chip</strong>
是<a href="https://api.flutter.dev/flutter/painting/AssetImage-class.html"><code>AssetImage 类</code></a>
的实现。<strong>Assets.images.chip.image(...)</strong>
返回<a href="https://api.flutter.dev/flutter/widgets/Image-class.html"><code>Image 类</code></a>
。<strong>Assets.images.chip.provider(...)</strong>
返回<a href="https://api.flutter.dev/flutter/painting/ImageProvider-class.html"><code>ImageProvider 类</code></a>
。<strong>Assets.images.chip.path</strong>
只返回路径字符串。<strong>Assets.images.chip.values</strong>
只返回值列表。
Widget build(BuildContext context) {
return Assets.images.chip.image();
}
Widget build(BuildContext context) {
return Assets.images.chip.image(
width: 120,
height: 120,
fit: BoxFit.scaleDown,
);
Widget build(BuildContext context) {
// Assets.images.chip.path = 'assets/images/chip3/chip3.jpg'
return Image.asset(Assets.images.chip.path);
}
如果你使用了 <a href="https://pub.dev/packages/flutter_svg">flutter_svg</a>
的SVG图像,你可以使用集成功能。
# pubspec.yaml
ds_flutter_gen:
integrations:
flutter_svg: true
flutter:
assets:
- assets/images/icons/paint.svg
Widget build(BuildContext context) {
return Assets.images.icons.paint.svg(
width: 120,
height: 120
);
}
可用集成
插件 | 文件扩展名 | 设置 | 使用 |
---|---|---|---|
flutter_svg | .svg | flutter_svg: true |
Assets.images.icons.paint.svg() |
flare_flutter | .flr | flare_flutter: true |
Assets.flare.penguin.flare() |
rive | .flr | rive: true |
Assets.rive.vehicles.rive() |
lottie | .json, .zip | lottie: true |
Assets.lottie.hamburgerArrow.lottie() |
在其他情况下,资源将以String
类的形式生成。
// 如果不使用集成。
final svg = SvgPicture.asset(Assets.images.icons.paint);
final json = await rootBundle.loadString(Assets.json.fruits);
ds_flutter_gen
还支持生成其他样式的Assets
类:
# pubspec.yaml
ds_flutter_gen:
assets:
outputs:
# Assets.imagesChip
# style: camel-case
# Assets.images_chip
# style: snake-case
# Assets.images.chip (默认样式)
# style: dot-delimiter
flutter:
assets:
- assets/images/chip.png
根目录将被省略,如果它是assets
或asset
。
assets/images/chip3/chip.jpg => Assets.images.chip3.chip
assets/images/chip4/chip.jpg => Assets.images.chip4.chip
assets/images/icons/paint.svg => Assets.images.icons.paint
assets/images/icons/dart@test.svg => Assets.images.icons.dartTest
assets/json/fruits.json => Assets.json.fruits
pictures/ocean_view.jpg => Assets.pictures.oceanView
字体
只需遵循文档 使用自定义字体 来指定字体,然后ds_flutter_gen
将生成相关的Dart文件。
无需其他特定配置。
# pubspec.yaml
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
这些配置将在默认情况下在lib/gen/
目录下生成fonts.gen.dart
文件。
为包生成字体
如果你想要为一个包生成字体,
可以在ds_flutter_gen > fonts > outputs
下使用package_parameter_enabled
。
ds_flutter_gen:
fonts:
outputs:
package_parameter_enabled: true # <- 添加此行。
这会向生成的类添加包常量。例如:
class Fonts {
Fonts._();
static const String package = 'test';
static const String raleway = 'packages/$package/Raleway';
static const String robotoMono = 'packages/$package/RobotoMono';
}
使用示例
Text(
'Hi there, I\'m FlutterGen',
style: TextStyle(
fontFamily: FontFamily.robotoMono,
fontFamilyFallback: const [FontFamily.raleway],
),
)
颜色
ds_flutter_gen
支持从 XML 格式的文件生成颜色。
# pubspec.yaml
ds_flutter_gen:
colors:
inputs:
- assets/color/colors.xml
- assets/color/colors2.xml
ds_flutter_gen
可以基于name
属性和颜色十六进制值生成一个 <a href="https://api.flutter.dev/flutter/material/Colors-class.html">Color</a>
类。
如果元素具有type
属性,则将生成一种特殊颜色。
目前支持的特殊颜色类型:
<a href="https://api.flutter.dev/flutter/material/MaterialColor-class.html">MaterialColor</a>
<a href="https://api.flutter.dev/flutter/material/MaterialAccentColor-class.html">MaterialAccentColor</a>
<color name="milk_tea">#F5CB84</color>
<color name="cinnamon" type="material">#955E1C</color>
<color name="yellow_ocher" type="material material-accent">#DF9527</color>
这些配置将在默认情况下在lib/gen/
目录下生成colors.gen.dart
文件。
使用示例
Text(
'Hi there, I\'m FlutterGen',
style: TextStyle(
color: ColorName.denim,
),
更多关于Flutter自动生成代码插件ds_flutter_gen_runner的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter自动生成代码插件ds_flutter_gen_runner的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
ds_flutter_gen_runner
是一个用于 Flutter 项目的代码生成工具,它可以帮助开发者自动生成一些重复性的代码,例如路由生成、状态管理、模型类等,从而提高开发效率。以下是如何使用 ds_flutter_gen_runner
插件的基本步骤:
1. 添加依赖
首先,你需要在 pubspec.yaml
文件中添加 ds_flutter_gen_runner
的依赖。通常,它需要 build_runner
来执行代码生成任务。
dev_dependencies:
ds_flutter_gen_runner: ^版本号
build_runner: ^2.1.0
请确保将 ^版本号
替换为你实际需要的 ds_flutter_gen_runner
版本。
2. 创建配置文件
ds_flutter_gen_runner
通常需要一个配置文件来指定生成代码的规则。这个配置文件可以是一个 YAML 文件或 Dart 文件,具体取决于插件的实现。
例如,如果你需要生成路由代码,可能会有一个 ds_flutter_gen.yaml
文件:
routes:
- name: HomePage
path: '/home'
- name: SettingsPage
path: '/settings'
3. 运行代码生成器
在配置好依赖和配置文件后,你可以使用 build_runner
来生成代码。在终端中运行以下命令:
flutter pub run build_runner build
这条命令会执行代码生成任务,并根据配置文件生成相应的 Dart 代码。
4. 使用生成的代码
生成的代码通常会放在 lib/generated/
目录下(具体路径可能因插件而异)。你可以在你的项目中使用这些生成的代码,例如:
import 'generated/routes.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
routes: generatedRoutes,
initialRoute: '/home',
);
}
}
5. 持续集成与开发
在开发过程中,你可能需要多次运行代码生成器。可以使用 watch
模式来自动检测文件变化并重新生成代码:
flutter pub run build_runner watch
这将使 build_runner
监视文件变化,并在需要时自动重新生成代码。
6. 清理生成的代码
如果你想清理生成的代码,可以运行以下命令:
flutter pub run build_runner clean
这将删除所有由 build_runner
生成的文件。
7. 示例
假设你正在使用 ds_flutter_gen_runner
生成路由代码,配置文件 ds_flutter_gen.yaml
如下:
routes:
- name: HomePage
path: '/home'
- name: SettingsPage
path: '/settings'
运行 flutter pub run build_runner build
后,生成的路由代码可能如下:
// lib/generated/routes.dart
import 'package:flutter/material.dart';
import 'package:my_app/pages/home_page.dart';
import 'package:my_app/pages/settings_page.dart';
final Map<String, WidgetBuilder> generatedRoutes = {
'/home': (context) => HomePage(),
'/settings': (context) => SettingsPage(),
};
然后在 main.dart
中使用这些生成的路由:
import 'package:flutter/material.dart';
import 'generated/routes.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
routes: generatedRoutes,
initialRoute: '/home',
);
}
}