【Flutter】l10n ローカライゼーション（多言語対応）に対応する

## Flutterのstableが1.22.0にアップデート
[1.22.0](https://medium.com/flutter/announcing-flutter-1-22-44f146009e5f)のアップデートに伴い、多言語対応が含まれました。
なので、早速試してみました。

[公式のドキュメントはこちら](https://docs.google.com/document/d/10e0saTfAv32OZLRmONy866vnaw0I2jwL8zukykpgWBc/edit)

## 完成イメージはこちら
[https://github.com/Tetsukick/enGolf](https://github.com/Tetsukick/enGolf)
[App Store はこちら](https://apps.apple.com/jp/app/engolf/id1507668448?l=en)
[Google Play Store はこちら](https://play.google.com/store/apps/details?id=com.tetsukick.engolf)

### 日本語版

<img width="250" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261934/718aa824-62ea-913e-9583-39b6d6cd6456.jpeg"><img width="250" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261934/11e6895d-b785-f1a7-0088-1d78dfbddd50.jpeg"><img width="250" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261934/40ffae49-3939-3438-3217-245752037e78.jpeg"><img width="250" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261934/a265e31d-0667-4050-b41a-02a0331b453a.jpeg">


### 英語版

<img width="250" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261934/3b8b2a5f-8bee-2441-df7e-437c425fbc02.jpeg"><img width="250" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261934/04d45726-82c7-9733-9686-8b1bffe0531c.jpeg"><img width="250" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261934/17fb3317-81a8-7525-9a72-28b73ffc521f.jpeg"><img width="250" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261934/7502902c-00b7-096e-1bad-8b41fa7cb566.jpeg">

### インドネシア語版

<img width="250" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261934/37b3110a-3a88-4f2a-a95d-390868e86cb1.jpeg"><img width="250" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261934/6f2fe71d-6f22-4521-5c25-0b2ec962c5f6.jpeg"><img width="250" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261934/74d442fd-8812-6fc3-4e5d-81cb252e5f4d.jpeg"><img width="250" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261934/cb8102c7-e022-51a2-a459-9fcd3f976baf.jpeg">


## STEP1: プラグインのインポート

pubspec.yamlに以下を追記。pub get を実行する度に多言語対応のファイルが自動生成されるようになります。

```pubspec.yaml
dependencies:
  flutter:
    sdk: flutter
  # Internationalization support.
  flutter_localizations:
    sdk: flutter
  intl: 0.16.1
  # the rest of your dependencies
flutter:
  # Adds code generation (synthetic package) support 
  generate: true
```

## STEP2: l10n.yamlファイルの生成

ルート直下に`l10n.yaml`を作成します。
作成後、以下を追記。

```l10n.yaml
arb-dir: lib/l10n
template-arb-file: app_en.arb
output-localization-file: app_localizations.dart
```

`arb-dir` は、l10nファイルのディレクトリを指定する。このディレクトリには ".arb" フォーマットのファイルを格納します。

`template-arb-file` アプリケーションがサポートするすべてのメッセージと、各メッセージの説明を定義するファイルを指定します。このファイルは arb-dir に作成する必要があります。

`output-localization-file` アプリケーションがインポートするDartクラスファイルを定義します。

## STEP3: 多言語対応ファイルを作成
lib/l10n配下に、`.arb`形式のファイルを生成します。

```app_en.arb
{
  "@@locale": "en",

  "rate": "Rate",
      "@rate": {
        "description": "rate title label"
      },

  "player": "Player",
      "@player": {
        "description": "number of player label"
      },

  "shake": "Shake!!",
      "@shake": {
        "description": "start create random number"
      },

  "allowDuplicateNumber": "Allow duplicate number",
      "@allowDuplicateNumber": {
        "description": "Allow duplicate number"
      },

  "noServiceMessage": "Not compatible with Android.\nPlease wait for a while as it is currently under development.",
      "@noServiceMessage": {
        "description": "Not compatible with Android.Please wait for a while as it is currently under development."
      },

  "feedback": "Feedback",
      "@feedback": {
        "description": "feedback"
      },

  "privacyPolicy": "Privacy policy",
      "@privacyPolicy": {
        "description": "Privacy policy"
      }
}
```

```app_ja.arb
{
  "@@locale": "ja",

  "rate": "レート",
  "player": "プレイヤー数",
  "shake": "乱数生成",
  "allowDuplicateNumber": "重複を許可",
  "noServiceMessage": "Androidには対応しておりません。\n現在開発中のためしばらくお待ち下さい。",
  "feedback": "フィードバック",
  "privacyPolicy": "プライバシー・ポリシー"
}
```

```app_id.arb
{
  "@@locale": "id",

  "rate": "menilai",
  "player": "Jumlah pemain",
  "shake": "Generasi acak",
  "allowDuplicateNumber": "Izinkan duplikasi",
  "noServiceMessage": "Tidak kompatibel dengan Android.\nHarap tunggu sebentar karena saat ini sedang dalam pengembangan.",
  "feedback": "Umpan balik",
  "privacyPolicy": "Rahasia pribadi"
}
```

上記作成後に、`flutter pub get`を実行して、ファイルを自動生成します。

## STEP4: localizationのdeligate

```dart:main.dart
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart'; // Add this line.

void main() {
 runApp(MyApp());
}

class MyApp extends StatelessWidget {
 @override
 Widget build(BuildContext context) {
   return MaterialApp(
     // Add the `localizationsDelegate` and `supportedLocales` lines.
     localizationsDelegates: AppLocalizations.localizationsDelegates,
     supportedLocales: AppLocalizations.supportedLocales,
     home: MyHomePage(title: 'Flutter Demo Home Page'),
   );
 }
}

```

## STEP5: アプリ内で使用する

プラグインのインポートをします。

```dart
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
```

Stringとして以下のように扱えます。

```dart
AppLocalizations.of(context).privacyPolicy
```