【Flutter】FlutterGen入門 アセット管理を効率化する方法

## FlutterGenとは
FlutterGenはFlutterプロジェクトでのアセット管理を効率化し、開発プロセスをスムーズにするためのツールです。

https://wasabeef.medium.com/fluttergen-25149caea94f

## できること
- **自動生成による直接アクセス**
リソースファイル（画像、フォント、カラーなど）へのアクセスコードを自動生成し、手動でのファイルパス記述が不要になり、リソースへのアクセスが簡単になります。
- **コード補完によるタイポの防止**
IDEのコード補完機能を活用して、リソース名のタイプミスを防止します。また正しいリソース名が自動的に提案され、開発速度と正確性が向上します。
- **静的解析によるエラー防止**
FlutterGenが生成するコードは静的解析ができ、存在しないファイルを参照している場合や、リソースの指定に誤りがある場合に、コンパイル時にエラーが検出されます。

## 環境
- Flutter 3.16.9
- パッケージは以下を参照（初期から追加したもののみ記載しています）
```pubspec.yaml
dev_dependencies:
  flutter_gen_runner: ^5.4.0
  build_runner: ^2.4.7
```

https://pub.dev/packages/flutter_gen_runner

https://pub.dev/packages/build_runner

## 管理方法
今回は画像、フォント、カラーの基本的な管理方法について説明します。
### 1.画像
#### (1)`pubspec.yaml`にアセットの指定を行います。（以下は例です）
```pubspec.yaml
flutter:
  assets:
    - assets/images/
```

画像配置例
![スクリーンショット 2024-02-04 10.45.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2658262/df84fe36-72af-f135-a6f3-e87b501b5db4.png)

#### (2) 自動生成
`build_runner`を使ってファイルを自動生成します。
```zsh
flutter pub run build_runner build --delete-conflicting-outputs  
```
`lib/gen/assets.gen.dart`にファイルが自動生成されます。

![スクリーンショット 2024-02-04 10.49.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2658262/599cf833-de59-2bf2-a3cd-88e91aca7a74.png)

こちらには、assetsディレクトリ内に配置した画像のパス情報が書いてあります。

#### (3) 使い方
通常の書き方だと以下のようになりますが、タイポ等に気づきにくいかとおもいます。
```dart
Image.asset(
  'assets/images/sample_image.png',
  width: 100,
  height: 100,
),
```
FlutterGenを使用する場合は、以下のように記述できます。
##### ①`Image クラス`として使う場合
```dart
Assets.images.sampleImage.image(
  width: 100,
  height: 100,
),
```

##### ②Stringとして使用する場合
```dart
Image.asset(
  Assets.images.sampleImage.path,
  width: 100,
  height: 100,
),
```

#### (4) SVGの場合
SVGを表示したい場合には有名なところでいうと[flutter_svg](https://pub.dev/packages/flutter_svg) を使うことが多いかと思います。
FlutterGenではインテグレーション設定があり、`pubspec.yaml`に次のように設定することで、flutter_svg のSvgPictureを出力することができます。

```pubspec.yaml
flutter_gen:
  integrations:
    flutter_svg: true
```

**通常**
```dart
SvgPicture.asset(
  Assets.images.sampleIcon.path,
  width: 30,
  height: 30,
),
```

**設定後**
```dart
Assets.images.sampleIcon.svg(
  width: 30,
  height: 30,
),
```
インテグレーション設定を行うことで、コードの統一性と簡潔さにより、何をしているのかが直感的に理解しやすくなります。
### 2.フォント
#### (1)`pubspec.yaml`でのフォントの設定
プロジェクトのpubspec.yamlファイルに、使用したいフォントと、そのフォントファイルへのパスを指定します。
例えば、RobotoMonoフォントを使用する場合、以下のように記述します。
```pubspec.yaml
fonts:
    - family: RobotoMono
      fonts:
        - asset: assets/fonts/RobotoMono-Regular.ttf
        - asset: assets/fonts/RobotoMono-Bold.ttf
          weight: 700
```
**配置例**

![スクリーンショット 2024-02-04 21.46.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2658262/293f58ed-2cb2-bffa-a0f8-452e12484fbc.png)


#### (2) 自動生成
`build_runner`を使ってファイルを自動生成します。
```zsh
flutter pub run build_runner build --delete-conflicting-outputs  
```
`lib/gen/assets.gen.dart`にファイルが自動生成されます。

![スクリーンショット 2024-02-04 21.40.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2658262/050d426d-f012-01c7-02a4-86a283346c6e.png)


#### (3) 使い方
フォントをDartコード内で使用する際は、自動生成されたFontFamilyクラスを通じて以下のように指定できます。
```dart
Text(
  'Hello, World!',
  style: TextStyle(
    fontFamily: FontFamily.robotoMono,
  ),
),
```

### 3.カラー
#### (1)`pubspec.yaml`でのカラーアセットの指定
プロジェクトのpubspec.yamlファイルにカラーアセットのパスを指定することで、カラー定義を一元管理できます。以下はその設定例です。
```pubspec.yaml
flutter_gen:
  colors:
    inputs:
      - assets/color/colors.xml
```
この設定により、assets/color/colors.xmlファイル内で定義されたカラーがflutter_genによって扱われるようになります。

**配置例**
プロジェクトのディレクトリにassets/color/colors.xmlファイルを配置します。
このファイルにはアプリケーションで使用するカラーの定義を含めます。
![スクリーンショット 2024-02-04 18.43.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2658262/31cc68dd-f5af-febe-0ee7-19dab1197290.png)

例えば、以下のように記述します。
```colors.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="black">#000000</color>
    <color name="coffee">#8CF5CB84</color>
</resources>
```
この方法の利点は、Figmaなどのデザインツールからカラーコードを直接コピーしてcolors.xmlに貼り付けるだけで済む点にあります。

さらに、`#8CF5CB84`のようにカラーコードの先頭にアルファ値を指定することで、カラーの透明度を細かく調整できます。ここで`8C`は透明度を、`F5CB84`はカラーをそれぞれ表しています。

透明度は16進数で00（完全に透明）からFF（完全に不透明）までの範囲で指定します。アルファ値の詳細な理解には、以下の記事が役立ちます。

https://qiita.com/CUTBOSS/items/a96fb369e5d1d8eda0da


なお、カラーコードの先頭のFF（完全に不透明）を省略することも可能です。省略した場合、色はデフォルトで不透明として扱われます。


:::note info
アルファ値を省略する場合、カラーコードをコピペする際の手間が省けます。透明度を設定したい特定のケースでのみアルファ値を追加することで、作業の効率化が図れます。

アルファ値を常に指定する場合（FFを含める）は、カラーコードの記述に一貫性が生まれ、カラー定義を読む際の明確性が向上します。

これらは、プロジェクトの具体的な要件やチームの方針に基づいて選択すること大切です。
:::

#### (2) 自動生成
`build_runner`を使ってファイルを自動生成します。
```zsh
flutter pub run build_runner build --delete-conflicting-outputs  
```
`lib/gen/assets.gen.dart`にファイルが自動生成されます。

![スクリーンショット 2024-02-04 18.45.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2658262/f24f89a0-a66a-1b02-ad4a-d58ac36236e4.png)

#### (3) 使い方
カラーをDartコード内で使用する際は、自動生成されたColorNameクラスを通じて以下のように指定できます。
```dart
Text(
  'Hello, World!',
  style: TextStyle(
    color: ColorName.black,
  ),
),
```

カラーコードの管理が簡単になりました。