Flutter自动生成代码插件ds_flutter_gen_core的使用
Flutter自动生成代码插件ds_flutter_gen_core的使用
ds_flutter_gen_core 是一个用于自动生成 Flutter 项目代码的插件。通过该插件,你可以自动为你的项目中的资源(如资产文件、字体、颜色等)生成对应的 Dart 类,从而避免直接使用字符串路径带来的潜在错误。
动机
直接使用字符串路径引用资源文件是不安全的。例如,在 pubspec.yaml
文件中配置了某个图像文件:
flutter:
assets:
- assets/images/profile.jpg
如果在引用时出现拼写错误:
Widget build(BuildContext context) {
return Image.asset('assets/images/profile.jpeg');
}
// The following assertion was thrown resolving an image codec:
// Unable to load asset: assets/images/profile.jpeg
为了避免这类问题,我们可以使用 ds_flutter_gen_core
自动生成的类来引用资源文件:
Widget build(BuildContext context) {
return Assets.images.profile.image();
}
安装过程
Pub Global
适用于 macOS、Linux 和 Windows。
dart pub global activate ds_flutter_gen
你可能需要设置你的环境变量路径:
export PATH="$PATH:$HOME/.pub-cache/bin"
作为 build_runner 的一部分
- 在
pubspec.yaml
中添加依赖项:
dev_dependencies:
build_runner:
ds_flutter_gen_runner:
- 运行
flutter pub get
来安装依赖项:
flutter pub get
- 使用
build_runner
生成代码:
dart run build_runner build
使用方法
运行 fluttergen
命令来生成代码:
fluttergen -h
fluttergen -c example/pubspec.yaml
配置文件
ds_flutter_gen_core
会基于 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_core
将生成相关的 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
文件。
生成 flavored 资源
如果你需要根据不同的风味生成资源,ds_flutter_gen_core
会生成相应的 flavors
字段。
print(MyAssets.images.chip4.flavors); // -> {'extern'}
排除生成某些资源
你可以使用 Glob
模式来排除特定的资源。
ds_flutter_gen:
assets:
exclude:
- folder-your-want-to-exclude/**
- specified-asset.jpg
为包生成资源
如果你希望为包生成资源,可以启用 package_parameter_enabled
。
ds_flutter_gen:
assets:
outputs:
package_parameter_enabled: true # <- 添加此行。
生成目录路径
如果你希望生成目录路径,可以启用 directory_path_enabled
。
ds_flutter_gen:
assets:
outputs:
directory_path_enabled: true # <- 添加此行。
包含额外元数据
在构建时,你可以包含额外的元数据。
ds_flutter_gen:
parse_metadata: true # <- 添加此行(默认值为 false)
使用示例
ds_flutter_gen_core
会生成 Image
类,如果资产文件是 Flutter 支持的图像格式。
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);
}
如果使用 flutter_svg
处理 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_core
还支持生成其他样式的 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_core
将生成相关的 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
文件。
为包生成字体
如果你希望为包生成字体,可以启用 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_core
支持从 XML 格式的文件生成颜色。
# pubspec.yaml
ds_flutter_gen:
colors:
inputs:
- assets/color/colors.xml
- assets/color/colors2.xml
ds_flutter_gen_core
可以根据 name
属性和颜色十六进制值生成 Color
类。如果元素具有 type
属性,则会生成特殊颜色。
当前支持的特殊颜色类型:
MaterialColor
MaterialAccentColor
<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,
),
)
已知问题
Bad State: No Element when using build_runner
如果你遇到这样的错误信息:
[SEVERE] flutter_gen_runner:flutter_gen_runner on $package$:
Bad state: No element
[SEVERE] Failed after 16.0s
则最有可能是因为你有一个自定义的 build.yaml
文件来配置 build_runner
。在这种情况下,只需将 pubspec.yaml
添加到 build.yaml
的 sources
部分即可。
targets:
$default:
sources:
include:
- pubspec.yaml # 添加此行
- ...
示例代码
import 'package:example_resources/gen/assets.gen.dart';
import 'package:flutter/material.dart';
import 'gen/assets.gen.dart';
import 'gen/colors.gen.dart';
import 'gen/fonts.gen.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
// await Firebase.initializeApp(
// options: DefaultFirebaseOptions.currentPlatform,
// );
runApp(MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
// 自动生成的字体来自 FlutterGen。
fontFamily: MyFontFamily.raleway,
primarySwatch: MyColorName.crimsonRed,
),
home: Scaffold(
appBar: AppBar(
title: const Text('FlutterGen'),
),
body: Center(
child: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
// 自动生成的图像来自 FlutterGen。
SizedBox(
width: 200,
height: 200,
child: MyAssets.flare.penguin.flare(
animation: 'walk',
fit: BoxFit.contain,
),
),
SizedBox(
width: 200,
height: 200,
child: MyAssets.rive.vehicles.rive(
fit: BoxFit.contain,
),
),
SizedBox(
width: 200,
height: 200,
child: MyAssets.lottie.hamburgerArrow.lottie(
fit: BoxFit.contain,
),
),
SizedBox(
width: 200,
height: 200,
child: MyAssets.lottie.geometricalAnimation.lottie(
fit: BoxFit.contain,
),
),
SizedBox(
width: 200,
height: 200,
child: MyAssets.lottie.alarmClockLottieV440.lottie(
fit: BoxFit.contain,
),
),
MyAssets.images.chip1.image(),
Container(
height: 400,
decoration: BoxDecoration(
image: DecorationImage(
image: MyAssets.images.chip1.provider(),
),
),
child: const Center(child: Text('Deco')),
),
// 使用 example_resource 包。
MyAssets.images.icons.kmm.svg(key: const Key('kmm_svg')),
MyAssets.images.icons.fuchsia.svg(),
MyAssets.images.icons.paint.svg(
width: 120,
height: 120,
),
// MyAssets.pictures.chip5.image(
// key: const Key("chip5"),
// width: 120,
// height: 120,
// fit: BoxFit.scaleDown,
// ),
// example_resource 包。
Text(MyAssets.images.icons.kmm.path),
Text(MyAssets.images.icons.kmm.keyName),
Text(ResAssets.images.dart.path),
Text(ResAssets.images.dart.keyName),
ResAssets.images.flutter3.image(),
ResAssets.images.dart.svg(),
SizedBox(
width: 200,
height: 200,
child: ResAssets.images.skills.rive(
fit: BoxFit.contain,
),
),
SizedBox(
width: 200,
height: 200,
child: ResAssets.images.favorite.flare(
shouldClip: false,
),
),
SizedBox(
width: 200,
height: 200,
child: ResAssets.images.runningCarOnRoad.lottie(
fit: BoxFit.contain,
),
),
const Text(
'Hi there, I\'m FlutterGen',
style: TextStyle(
// 自动生成的颜色来自 FlutterGen。
color: MyColorName.black60,
// 自动生成的字体来自 FlutterGen。
fontFamily: MyFontFamily.robotoMono,
fontFamilyFallback: [MyFontFamily.raleway],
),
),
],
),
),
),
),
));
}
更多关于Flutter自动生成代码插件ds_flutter_gen_core的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter自动生成代码插件ds_flutter_gen_core的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
ds_flutter_gen_core
是一个用于自动生成 Flutter 代码的插件,它可以帮助开发者通过注解和代码生成的方式减少重复代码的编写。使用这个插件,你可以通过定义一些注解,然后让插件自动生成相关的代码,如路由、序列化、依赖注入等。
安装步骤
-
添加依赖
在你的pubspec.yaml
文件中添加ds_flutter_gen_core
和build_runner
依赖:dependencies: ds_flutter_gen_core: ^版本号 dev_dependencies: build_runner: ^版本号
请确保将
^版本号
替换为实际的版本号。 -
创建注解
你可以定义自己的注解类。例如,定义一个用于生成路由的注解:import 'package:ds_flutter_gen_core/ds_flutter_gen_core.dart'; class RouteAnnotation { final String path; const RouteAnnotation(this.path); }
-
使用注解
在你的代码中使用定义的注解。例如,在一个 Widget 上使用RouteAnnotation
:[@RouteAnnotation](/user/RouteAnnotation)('/home') class HomeScreen extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('Home'), ), body: Center( child: Text('Welcome to the Home Screen!'), ), ); } }
-
生成代码
使用build_runner
来生成代码。在终端中运行以下命令:flutter pub run build_runner build
这将根据你定义的注解自动生成相关的代码。
示例:生成路由
假设你想生成路由相关的代码,你可以按照以下步骤操作:
-
定义路由注解
定义一个RouteAnnotation
类,如前所述。 -
生成路由代码
使用ds_flutter_gen_core
提供的代码生成器来生成路由代码。你可以在lib
目录下创建一个routes.dart
文件,并在其中生成路由映射。import 'package:flutter/material.dart'; import 'package:ds_flutter_gen_core/ds_flutter_gen_core.dart'; part 'routes.g.dart'; [@RouteGenerator](/user/RouteGenerator)() class AppRoutes { static const String home = '/home'; } Map<String, WidgetBuilder> get routes => _$routes;
-
运行代码生成器
运行flutter pub run build_runner build
,ds_flutter_gen_core
将会生成routes.g.dart
文件,其中包含路由映射。 -
使用生成的路由
在你的main.dart
中使用生成的路由:import 'package:flutter/material.dart'; import 'routes.dart'; void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( initialRoute: AppRoutes.home, routes: routes, ); } }