flutter_gen
the flutter code generator for your assets, fonts, colors, … — get rid of all string-based apis.
motivation
using asset path string directly is not safe.
# pubspec.yaml
flutter:
assets:
- assets/images/profile.jpg
❌ bad
what would happen if you made a typo?
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
⭕️ good
we want to use it safely.
widget build(buildcontext context) {
return assets.images.profile.image();
}
installation
homebrew
works with macos and linux.
$ brew install fluttergen/tap/fluttergen
pub global
works with macos, linux and windows.
$ dart pub global activate flutter_gen
you might need to set up your path.
as a part of build_runner
- add [build_runner] and [fluttergen] to your package’s pubspec.yaml file:
dev_dependencies:
build_runner:
flutter_gen_runner:
- install [fluttergen]
$ flutter pub get
- use [fluttergen]
$ flutter packages pub run build_runner build
usage
run fluttergen
after the configuration pubspec.yaml
.
$ fluttergen -h
$ fluttergen -c example/pubspec.yaml
configuration file
[fluttergen] generates dart files based on the key flutter
and flutter_gen
of pubspec.yaml
.
default configuration can be found here.
# pubspec.yaml
# ...
flutter_gen:
output: lib/gen/ # optional (default: lib/gen/)
line_length: 80 # optional (default: 80)
# optional
integrations:
flutter_svg: true
flare_flutter: 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
available parsers
assets
just follow the doc adding assets and images#specifying assets to specify assets, then [fluttergen] will generate related dart files.
no other specific configuration is required.
ignore duplicated.
# pubspec.yaml
flutter:
assets:
- assets/images/
- assets/images/chip3/chip.jpg
- assets/images/chip4/chip.jpg
- assets/images/icons/paint.svg
- assets/json/fruits.json
- assets/flare/penguin.flr
- pictures/ocean_view.jpg
these configurations will generate assets.gen.dart
under the lib/gen/
directory by default.
usage example
[fluttergen] generates image class if the asset is flutter supported image format.
example results of assets/images/chip.jpg
:
assets.images.chip
is an implementation ofassetimage class
.assets.images.chip.image(...)
returnsimage class
.assets.images.chip.path
just returns the path string.
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) {
// assets.images.chip.path = 'assets/images/chip3/chip3.jpg'
return image.asset(assets.images.chip.path);
}
if you are using svg images with flutter_svg you can use the integration feature.
# pubspec.yaml
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
);
}
available integrations
packages | file extension | setting | usage |
---|---|---|---|
flutter_svg | .svg | flutter_svg: true |
assets.images.icons.paint.svg() |
flare_flutter | .flr | flare_flutter: true |
assets.flare.penguin.flare() |
in other cases, the asset is generated as string class.
// if don't use the integrations.
final svg = svgpicture.asset(assets.images.icons.paint);
final json = await rootbundle.loadstring(assets.json.fruits);
[fluttergen] also support generating other style of assets
class:
# pubspec.yaml
flutter_gen:
assets:
# assets.imageschip
# style: camel-case
# assets.images_chip
# style: snake-case
# assets.images.chip (default style)
# style: dot-delimiter
flutter:
assets:
- assets/images/chip.png
the root directory will be omitted if it is either assets
or 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/json/fruits.json => assets.json.fruits
pictures/ocean_view.jpg => assets.pictures.oceanview
example of code generated by fluttergen
/// generated code - do not modify by hand
/// *****************************************************
/// fluttergen
/// *****************************************************
import 'package:flutter/widgets.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:flutter/services.dart';
import 'package:flare_flutter/flare_actor.dart';
import 'package:flare_flutter/flare_controller.dart';
class $picturesgen {
const $picturesgen();
assetgenimage get chip5 => const assetgenimage('pictures/chip5.jpg');
}
class $assetsflaregen {
const $assetsflaregen();
flaregenimage get penguin => const flaregenimage('assets/flare/penguin.flr');
}
class $assetsimagesgen {
const $assetsimagesgen();
assetgenimage get chip1 => const assetgenimage('assets/images/chip1.jpg');
assetgenimage get chip2 => const assetgenimage('assets/images/chip2.jpg');
$assetsimageschip3gen get chip3 => const $assetsimageschip3gen();
$assetsimageschip4gen get chip4 => const $assetsimageschip4gen();
$assetsimagesiconsgen get icons => const $assetsimagesiconsgen();
assetgenimage get logo => const assetgenimage('assets/images/logo.png');
assetgenimage get profile => const assetgenimage('assets/images/profile.jpg');
}
class $assetsjsongen {
const $assetsjsongen();
string get fruits => 'assets/json/fruits.json';
}
class $assetsmoviegen {
const $assetsmoviegen();
string get theearth => 'assets/movie/the_earth.mp4';
}
class $assetsunknowngen {
const $assetsunknowngen();
string get unknownmimetype => 'assets/unknown/unknown_mime_type.bk';
}
class $assetsimageschip3gen {
const $assetsimageschip3gen();
assetgenimage get chip3 =>
const assetgenimage('assets/images/chip3/chip3.jpg');
}
class $assetsimageschip4gen {
const $assetsimageschip4gen();
assetgenimage get chip4 =>
const assetgenimage('assets/images/chip4/chip4.jpg');
}
class $assetsimagesiconsgen {
const $assetsimagesiconsgen();
svggenimage get fuchsia =>
const svggenimage('assets/images/icons/fuchsia.svg');
svggenimage get kmm => const svggenimage('assets/images/icons/kmm.svg');
svggenimage get paint => const svggenimage('assets/images/icons/paint.svg');
}
class assets {
assets._();
static const $assetsflaregen flare = $assetsflaregen();
static const $assetsimagesgen images = $assetsimagesgen();
static const $assetsjsongen json = $assetsjsongen();
static const $assetsmoviegen movie = $assetsmoviegen();
static const $assetsunknowngen unknown = $assetsunknowngen();
static const $picturesgen pictures = $picturesgen();
}
class assetgenimage extends assetimage {
const assetgenimage(string assetname)
: _assetname = assetname,
super(assetname);
final string _assetname;
image image({
key key,
imageframebuilder framebuilder,
imageloadingbuilder loadingbuilder,
imageerrorwidgetbuilder errorbuilder,
string semanticlabel,
bool excludefromsemantics = false,
double width,
double height,
color color,
blendmode colorblendmode,
boxfit fit,
alignmentgeometry alignment = alignment.center,
imagerepeat repeat = imagerepeat.norepeat,
rect centerslice,
bool matchtextdirection = false,
bool gaplessplayback = false,
bool isantialias = false,
filterquality filterquality = filterquality.low,
}) {
return image(
key: key,
image: this,
framebuilder: framebuilder,
loadingbuilder: loadingbuilder,
errorbuilder: errorbuilder,
semanticlabel: semanticlabel,
excludefromsemantics: excludefromsemantics,
width: width,
height: height,
color: color,
colorblendmode: colorblendmode,
fit: fit,
alignment: alignment,
repeat: repeat,
centerslice: centerslice,
matchtextdirection: matchtextdirection,
gaplessplayback: gaplessplayback,
isantialias: isantialias,
filterquality: filterquality,
);
}
string get path => _assetname;
}
class svggenimage {
const svggenimage(this._assetname);
final string _assetname;
svgpicture svg({
key key,
bool matchtextdirection = false,
assetbundle bundle,
string package,
double width,
double height,
boxfit fit = boxfit.contain,
alignmentgeometry alignment = alignment.center,
bool allowdrawingoutsideviewbox = false,
widgetbuilder placeholderbuilder,
color color,
blendmode colorblendmode = blendmode.srcin,
string semanticslabel,
bool excludefromsemantics = false,
clip clipbehavior = clip.hardedge,
}) {
return svgpicture.asset(
_assetname,
key: key,
matchtextdirection: matchtextdirection,
bundle: bundle,
package: package,
width: width,
height: height,
fit: fit,
alignment: alignment,
allowdrawingoutsideviewbox: allowdrawingoutsideviewbox,
placeholderbuilder: placeholderbuilder,
color: color,
colorblendmode: colorblendmode,
semanticslabel: semanticslabel,
excludefromsemantics: excludefromsemantics,
clipbehavior: clipbehavior,
);
}
string get path => _assetname;
}
class flaregenimage {
const flaregenimage(this._assetname);
final string _assetname;
flareactor flare({
string boundsnode,
string animation,
boxfit fit = boxfit.contain,
alignment alignment = alignment.center,
bool ispaused = false,
bool snaptoend = false,
flarecontroller controller,
flarecompletedcallback callback,
color color,
bool shouldclip = true,
bool sizefromartboard = false,
string artboard,
bool antialias = true,
}) {
return flareactor(
_assetname,
boundsnode: boundsnode,
animation: animation,
fit: fit,
alignment: alignment,
ispaused: ispaused,
snaptoend: snaptoend,
controller: controller,
callback: callback,
color: color,
shouldclip: shouldclip,
sizefromartboard: sizefromartboard,
artboard: artboard,
antialias: antialias,
);
}
string get path => _assetname;
}
fonts
just follow the doc use a custom font to specify fonts, then [fluttergen] will generate related dart files.
no other specific configuration is required.
ignore duplicated.
# 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
these configurations will generate fonts.gen.dart
under the lib/gen/
directory by default.
usage example
text(
'hi there, i'm fluttergen',
style: textstyle(
fontfamily: fontfamily.robotomono,
fontfamilyfallback: const [fontfamily.raleway],
),
example of code generated by fluttergen
/// generated code - do not modify by hand
/// *****************************************************
/// fluttergen
/// *****************************************************
class fontfamily {
fontfamily._();
static const string raleway = 'raleway';
static const string robotomono = 'robotomono';
}
colors
[fluttergen] supports generating colors from xml format files.
ignore duplicated.
# pubspec.yaml
flutter_gen:
colors:
inputs:
- assets/color/colors.xml
- assets/color/colors2.xml
[fluttergen] can generate a color class based on the name
attribute and the color hex value.
if the element has the attribute type
, then a specially color will be generated.
currently supported special color types:
noticed that there is no official material color generation algorithm. the implementation is based on the mcg project.
<color name="milk_tea">#f5cb84</color>
<color name="cinnamon" type="material">#955e1c</color>
<color name="yellow_ocher" type="material material-accent">#df9527</color>
these configurations will generate colors.gen.dart
under the lib/gen/
directory by default.
usage example
text(
'hi there, i'm fluttergen',
style: textstyle(
color: colorname.denim,
),
example of code generated by fluttergen
/// generated code - do not modify by hand
/// *****************************************************
/// fluttergen
/// *****************************************************
import 'package:flutter/painting.dart';
import 'package:flutter/material.dart';
class colorname {
colorname._();
static const color black = color(0xff000000);
static const color black30 = color(0x4d000000);
static const color black40 = color(0x66000000);
static const color black50 = color(0x80000000);
static const color black60 = color(0x99000000);
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),
},
);
static const color gray410 = color(0xff979797);
static const color gray70 = color(0xffeeeeee);
static const color white = color(0xffffffff);
static const materialcolor yellowocher = materialcolor(
0xffdf9527,
<int, color>{
50: color(0xfffbf2e5),
100: color(0xfff5dfbe),
200: color(0xffefca93),
300: color(0xffe9b568),
400: color(0xffe4a547),
500: color(0xffdf9527),
600: color(0xffdb8d23),
700: color(0xffd7821d),
800: color(0xffd27817),
900: color(0xffca670e),
},
);
static const materialaccentcolor yellowocheraccent = materialaccentcolor(
0xffffbca3,
<int, color>{
100: color(0xffffe8e0),
200: color(0xffffbca3),
400: color(0xffffa989),
700: color(0xffff9e7a),
},
);
}
default configuration
the following are the default settings.
the options you set in pubspec.yaml
will override the corresponding default options.
flutter_gen:
output: lib/gen/
line_length: 80
null_safety: true
integrations:
flutter_svg: false
flare_flutter: false
assets:
enabled: true
package_parameter_enabled: false
style: dot-delimiter
fonts:
enabled: true
colors:
enabled: true
inputs: []
flutter:
assets: []
fonts: []
Comments are closed.