カウンターアプリを多言語対応してみた

2022/1/14
こちらの記事、[さくしん](https://twitter.com/SakushinFlutter)さんの記事と内容モロに被っていました、、、
ほぼ同内容ですので、合わせてぜひ読んでみてください。

https://flutter.salon/flutter/l10n/

------------------------------------------------

あなたのアプリ、世界に向けてリリースしていますか？

世界に向けてリリースする際に重要になるのが
言語をユーザーのスマホの言語設定に合わせて変化させる機能です。
これを「多言語対応」と今回は呼ぶことにします。

今回、この多言語対応のサンプルアプリとして、
Flutterのプロジェクトを作成した際に作られるカウンターアプリを
日本語に対応させたものを作成しました。

本記事では、下記を解説します。

- アプリの紹介
- 対応内容の詳細

##アプリの紹介##
作成したアプリの紹介です。
とはいえ、見た目はカウンターアプリと一緒です。
基本環境は英語、
スマホの言語設定を日本語にした場合は日本語が表示されるように作成しています。

###基本環境####
<img width="300" alt="Screenshot_1641447214.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1694109/592fa9c1-5afe-8bdc-9e7f-b92fb9389aa1.png">

###日本語環境###
<img width="300" alt="Screenshot_1641447157.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1694109/061518a4-49b1-95fb-587b-4033598c1cf3.png">

今回作成したアプリは、GitHubにて公開しています。
yamlファイルやarbファイルなど、みていただきたいファイルが複数あります。
ぜひ参考にしてみてください。

https://github.com/Umigishi-Aoi/localization

##対応内容の詳細##

対応内容の詳細を解説します。
とはいえ、行なっている内容は公式ドキュメントで解説されている内容に準じています。

https://docs.flutter.dev/development/accessibility-and-localization/internationalization

今回も公式ドキュメントに則って解説していきます。

###パッケージの追加###
pubspec.yamlに、
``flutter_localizations``パッケージと``intl``パッケージを以下のように追加します。

```yaml:pubspec.yaml
dependencies:
  flutter:
    sdk: flutter
  flutter_localizations:
    sdk: flutter
  intl: ^0.17.0
```

コマンドでの追加でなく、pubspec.yamlに直接打ち込んでのパッケージ追加をしてください。

###generateフラグの追加###
pubspec.yamlの下方にあるflutterタグの部分にgenerateフラグを追加します。

```yaml:pubspec.yaml
flutter:
  generate: true
```

追加が完了したらPub get をしましょう。

###l10n.yamlファイルの作成###
プロジェクトルート(pubspec.yamlファイルと同じ階層)に、l10n.yamlファイルを作成します。
内容は以下の通りです。

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

今回は英語を基礎言語とするため、``template-arb-file``の指定をapp_en.arbとしています。
日本語を基礎言語とする場合はapp_ja.arbとしてください。

###基礎言語のarbファイルの作成###
基礎となる言語(デフォルトで表示させたい言語)の定義を行なっていきます。
libディレクトリにl10nディレクトリを作成し、その中にapp_en.arbファイルを作成します。

arbファイルの内容は以下の通りです。

```:app_en.arb
{
  "title": "Flutter Demo Home Page",
  "@title": {
    "description": "to show title"
  },
  "explanation": "You have pushed the button this many times:",
  "@explanation": {
    "description": "to show explanation"
  },
  "tooltip": "Increment",
  "@tooltip": {
    "description": "to show tooltip"
  }
}
```

arbファイルの詳細は、こちらの記事がわかりやすかったです。

https://qiita.com/yukihiroK/items/d431036401ae5bbc06f9

``"title"``の部分はリソースIDを表しています。
その後に続く部分(``"Flutter Demo Home Page"``)が実際に表示する文章部分になります。

今回の例だと、3つ文章がある、ということになります。

###追加言語のarbファイルの作成###
続いて、翻訳となる言語の定義を行なっていきます。
app_en.arbファイルと同様、l10nディレクトリの中に、app_ja.arbファイルを作成します。

```:app_ja.arb
{
  "title": "Flutter デモ ホームページ",
  "explanation": "あなたがボタンを押した回数",
  "tooltip": "増加"
}
```

リソースIDに対し、対応し訳となる日本語の文章を定義しています。

###多言語対応用dartファイルの自動生成###

ここまで作成した状態でアプリの実行をするか、
``flutter gen-l10n``コマンドをターミナルで実行すると、
多言語対応用のdartファイルが自動生成されます。
生成されたファイルは、``${FLUTTER_PROJECT}/.dart_tool/flutter_gen/gen_l10n.``に保存されます。

###自動生成ファイルのインポート###
dartファイルで多言語対応するためには、上で自動生成したファイルのインポートが必要です。
以下の文でファイルのインポートを行います。

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

###MaterialApp内の設定###
dartファイルの具体的な記述をしていきます。
``MaterialApp``の``localizationsDelegates``と``supportedLocales``のプロパティを以下のように設定します。

```dart:main.dart
//省略

　　　　@override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      localizationsDelegates: AppLocalizations.localizationsDelegates,　　　　//ここと
      supportedLocales: AppLocalizations.supportedLocales,  //ここ

//省略
```

###arbファイルで定義した文章の使用###
長かったですが、ここまでで準備は完了です。
実際に定義した文章を使用していきます。

以下のように記載することで、リソースIDに対応するStringを取得できます。

```dart
AppLocalizations.of(context)!.リソースID
```

今回のカウンターアプリでの使用例は以下の通りです。

```dart:main.dart
//省略

      home: Builder(　　　　　　　　　　　　　　　　
        builder: (context) {
          return MyHomePage(title: AppLocalizations.of(context)!.title);　//ここ
        }
　　　　　　　　　　　　　) //　１
//省略
            Text(
              AppLocalizations.of(context)!.explanation,　//ここ
            ),
//省略
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: AppLocalizations.of(context)!.tooltip,　//ここ
        child: const Icon(Icons.add),
      ), // This trailing comma makes auto-formatting nicer for build methods.
//省略
```

//1　
``MaterialApp``直下では``context``が``locale``の情報を持っていないため、
``AppLocalizations.of(context)``が``null``となりエラーが発生します。
そのため、``Builder``をかませて運用しています。

以上、対応内容の解説でした。

##まとめ##

多言語対応のサンプルアプリとして、
Flutterのプロジェクトを作成した際に作られるカウンターアプリを
日本語に対応させたものを紹介しました。

また対応内容の詳細について解説を行いました。

実装はアプリ作成の初期段階で行うことをお勧めします。
準備が大変ですが、一度実装できてしまえば簡単に多言語対応できます。

ぜひやってみてください。