😎

Flutterのアセットを楽に使う

2023/06/17に公開

従来のアセット管理

Flutterアプリの開発で、ローカルに保存した画像を表示することが多いです。

そのとき、以下のように実装するのは一般的だと思います。

# pubspec.yaml
flutter:
  assets:
    - assets/images/avatar.jpg
Widget build(BuildContext context) {
  return Image.asset('assets/images/avatar.jpg');
}

しかし、この方法にはいくつかの問題点があります。

  • タイプミスや存在しないリソースへの参照
  • 開発効率や可読性の低下

リソースのパスを書き間違えたり、pubspec.yamlの設定を忘れたりしたとしても、コンパイルエラーが発生しないので、バグったことを気づかないままリリースしてしまう可能性があります。

このリスクを解消するために、flutter_genというライブラリをご紹介したいと思います。

FlutterGenとは

flutter_genは、R.javaR.swiftのような、画像、フォント、カラーなどのリソースへ安全にアクセスできるようにするためのコード自動生成ライブラリです[1]

導入

  • Homebrew(macOS and Linux)
$ brew install FlutterGen/tap/fluttergen
  • Dart package(macOS, Linux and Windows)
$ dart pub global activate flutter_gen
  • Flutter package
# pubspec.yaml
dev_dependencies:
  build_runner:
  flutter_gen_runner:

設定

デフォルトの設定値は以下になります。

# pubspec.yaml
# ...

flutter_gen:
  # Optional
  output: lib/gen/
  # Optional
  line_length: 80

  # Optional
  integrations:
    flutter_svg: false
    flare_flutter: false
    rive: false
    lottie: false

  assets:
    # Optional
    enabled: true
    # Optional
    outputs:
      # Optional
      # Set to true if you want this package to be a package dependency
      # See: https://flutter.dev/docs/development/ui/assets-and-images#from-packages
      package_parameter_enabled: false
      # Optional
      # Available values:
      # - camel-case
      # - snake-case
      # - dot-delimiter
      style: dot-delimiter
      class_name: Assets
    # Ignore unwanted files
    exclude: []

  fonts:
    # Optional
    enabled: true
    # Optional
    outputs:
      class_name: FontFamily

  colors:
    # Optional
    enabled: true
    # Optional
    inputs: []
    # Optional
    outputs:
      class_name: ColorName

pubspec.yamlflutter_genの設定を追加してカスタマイズできます。

例えば、SVG画像を表示したい場合は以下ように設定します。

# pubspec.yaml
# ...

flutter_gen:
  integrations:
    # flutter_svgを利用します
    # https://pub.dev/packages/flutter_svg
    flutter_svg: true

flutter:
  # ...

  assets:
    - assets/images/avatar.svg

生成

  1. パッケージをインストール
$ flutter pub get
  1. コードを生成
$ flutter pub run build_runner build --delete-conflicting-outputs

使用

  • 画像
Widget build(BuildContext context) {
  return Assets.images.avatar.image(
    width: 120,
    height: 120,
    fit: BoxFit.scaleDown,
  );
}

Widget build(BuildContext context) {
  // Same as Image.asset('assets/images/avatar.jpg')
  return Image.asset(Assets.images.avatar.path);
}

Widget build(BuildContext context) {
  // Use flutter_svg
  return Assets.images.avatar.svg(
    width: 120,
    height: 120,
    fit: BoxFit.scaleDown,
  );
}
  • フォント
flutter:
  # ...

  fonts:
    - family: MyFont
      fonts:
        - asset: fonts/MyFont-Regular.ttf
        - asset: fonts/MyFont-Bold.ttf
ThemeData(
  fontFamily: FontFamily.myFont,
)

既知の問題

Bad state: No element

build_runnerを実行したらBad state: No elementというエラーが出て失敗します。

build.yamlを作成してbuild_runnerの設定をカスタマイズすると発生します。

この場合、build.yamlpubspec.yamlの依頼を追加すればエラーを解消できます。

targets:
  $default:
    sources:
      include:
        - pubspec.yaml  # add this line

Bad state: Unable to generate package graph

pubspec.yamlgenerate: trueを設定していることが原因で、削除すればエラーを解消できます。

# pubspec.yaml
flutter:
  generate: true <--- ⚠️Remove this line⚠️

Flutterの多言語対応を入れている場合、l10n.yamlsynthetic-package: falseを設定する必要もあります。

# l10n.yaml
arb-dir: lib/l10n
template-arb-file: app_en.arb
output-localization-file: app_localizations.dart
synthetic-package: false <--- ⚠️Add this line⚠️

最後に

FlutterGenを導入することによって、画像などのアセットを安全かつ便利に管理できるようになりました。

これからもFlutter開発を楽しんでいきましょう。

脚注
  1. 詳しい内容は、ライブラリ作者の記事をお読みください。 ↩︎

GitHubで編集を提案

Discussion