FlutterでLocalizationする

[公式のInternationalizing Flutter apps](https://flutter.dev/docs/development/accessibility-and-localization/internationalization)の通りにやると多言語対応できます。

また、[ほぼ同じ内容でよりわかりやすい記事](https://qiita.com/tetsukick/items/962505028d14006af370)がありましたのでこちらを読むのが早いかなと思います。

---

Flutterの多言語対応の全体の流れは以下のようになります。

- MaterialAppの多言語対応設定をする
- localization用の翻訳ファイルを作成する
- Viewで翻訳ファイルを呼び出す

# MaterialAppの多言語対応設定をする
## flutter_localizations パッケージを追加する

### `pubspec.yaml`に`flutter_localizations`を追加する
```pubspec.yaml
// ...
dependencies:
  flutter:
    sdk: flutter
  flutter_localizations: # 追加
    sdk: flutter # 追加
// ...
```

## MaterialAppのdelegateと対応localesを設定

```dart
import 'package:flutter_localizations/flutter_localizations.dart';

// ...

MaterialApp(
 localizationsDelegates: [
   // localizations delegateを追加
   AppLocalizations.delegate,
   GlobalMaterialLocalizations.delegate,
   GlobalWidgetsLocalizations.delegate,
   GlobalCupertinoLocalizations.delegate,
 ],
 supportedLocales: [
    const Locale('en', ''), // 英語
    const Locale('ja', ''), // 日本語
    // ... 他のlocaleを追加
  ],
  // ...
)
```

# localization用の翻訳ファイルを作成する
## intlパッケージを追加する
```pubspec.yaml
dependencies:
  flutter:
    sdk: flutter
  flutter_localizations:
    sdk: flutter
  intl: ^0.16.1 # 追加
```

## pubspec.yamlにgenerate flagを追加する
これによってpub get時に多言語対応のファイルが自動生成されるようになります。

```pubspec.yaml
# The following section is specific to Flutter.
flutter:
  generate: true # 追加
```

## l10n.yamlを追加する
ルートディレクトリにl10n.yamlを追加して、以下を記述する

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

これにより以下の設定がなされます。

- json形式の翻訳ファイルの設置場所を`lib/l10n`と設定
- 翻訳ファイルのテンプレートを `app_en.arb`と設定
- 生成するl10n用dartファイルを `app_localizations.dart`と設定

## l10n.yamlで設定した`lib/l10n`に`app_en.arb`を設置する

```app_en.arb
{
    "helloWorld": "Hello World!",
    "@helloWorld": {
        "description": "The conventional newborn programmer greeting"
    },
    "since": "Since",
    "@since": {
        "description": "Since {YEAR}",
        "placeholders": {
            "YEAR": {
                "example": "2020",
                "description": "created year"
            }
        }
    }
}
```

`since`はプレースホルダを利用しています。
その他のarbの使い方は[こちら](https://localizely.com/flutter-arb/)を参考にしてみてください。

## `app_ja.arb`を設置する
```app_ja.arb
{
    "@@locale": "ja",
    "helloWorld": "こんにちは、世界！",
    "since": "{YEAR}年からやってます"
}
```

## `/flutter_gen/gen_l10n`を生成する
`pub get`すると`/flutter_gen/gen_l10n`が生成されるので確認する

# Viewで翻訳ファイルを呼び出す
```dart
body: Center(
  child: Column(
    mainAxisAlignment: MainAxisAlignment.center,
    children: <Widget>[
      Text(
        AppLocalizations.of(context).helloWorld,
        style: Theme.of(context).textTheme.headline2,
      ),
      Text(
        AppLocalizations.of(context).since(2020),
        style: Theme.of(context).textTheme.headline2,
      ),
      Text(
        'You have pushed the button this many times:',
      ),
      Text(
        '$_counter',
        style: Theme.of(context).textTheme.headline4,
      ),
    ],
  ),
),
```

# 表示
それぞれの表示は以下のようになります。

<img width=300, src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/779879/bb5961b3-779a-6f07-320f-03b780964069.png">
<img width=300, src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/779879/396ede28-1977-0d4c-ec14-8be785f57ce8.png">


---

記事にすると煩雑に思えますが、やってみると簡単です。
ぜひやってみてください。