[Flutter]多言語化対応で、アプリをグローバル化しよう！

## 概要
少々大袈裟なタイトルですが・・・
どうせアプリをリリースするなら、日本だけでなく世界中の方に使ってもらいたいですよね！

Flutterは、多言語対応を容易に行うことができます！
ユーザーの言語設定に応じた表示が可能になるということです。

本記事では、Flutterアプリを日本語、英語、中国語
に対応させるための具体的な手順を解説します！

### サンプル(日本語)

![スクリーンショット 2024-10-20 19.09.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/945342/99df716e-034e-f29a-f061-0cb25eb8729d.png)

### サンプル(英語)

![スクリーンショット 2024-10-20 19.09.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/945342/a80a4cbf-3fb5-2cb2-dc59-8012fbabad29.png)


## 多言語化の説明
Flutterには、**flutter_localizations**パッケージが標準で用意されており、
多言語対応を行います。
また**intl**パッケージを利用することで、ローカライズされた文字列を管理しやすくします。

## パッケージをインストールしよう
Flutterで多言語化を実現するために、以下のパッケージを使用します。

・flutter_localizations: Flutterの標準ローカライゼーションサポート。
・intl: 国際化とローカライゼーションをサポートするパッケージ。
これらのパッケージを使って、アプリに多言語対応を追加します！

### 参考URL

https://pub.dev/packages/flutter_localization

https://pub.dev/packages/intl

### pubspec.yaml
pubspec.yamlに記載でもOKです。

```pubspec.yaml
dependencies:
  flutter:
    sdk: flutter
  flutter_localizations: # 上記記載の多言語ライブラリ
    sdk: flutter  
  intl: "^0.17.0" # format等関連ライブラリ
  
flutter:
  generate: true #自動生成フラグの有効化
```

その後以下コマンドで依存関係をインストールします。

```bash
flutter pub get
```

## 多言語対応の設定
次にFlutterアプリで多言語対応を有効にするため、MaterialAppの設定を行います。

```main.dart
import 'package:flutter/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:intl/intl.dart';
import 'l10n/l10n.dart'; // l10nファイルをインポート

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      
      // 多言語化設定
      // ==============================================
      locale: Locale('en'), // デフォルト言語を英語に設定
      supportedLocales: L10n.all, // 対応する言語を設定
      localizationsDelegates: [
        AppLocalizations.delegate,
        GlobalMaterialLocalizations.delegate,
        GlobalWidgetsLocalizations.delegate,
        GlobalCupertinoLocalizations.delegate,
      ],
      // ==============================================
      
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(AppLocalizations.of(context)!.title),
      ),
      body: Center(
        child: Text(AppLocalizations.of(context)!.welcome),
      ),
    );
  }
}
```

## l10nのファイル作成
Flutterでは、l10n（localization）ファイルを使って、
各言語に対応するテキストを管理します。

### そもそもl10nって？
アプリケーションの多言語対応のために使われるリソースファイルです。
各言語に対応するテキストがJSON形式で定義され、
「.arb」ファイルとして管理されています。

:::note info
arb (Application Resource Bundle)
:::

### l10nファイルを作成してみよう！

**lib/l10n**ディレクトリを作成し、
その中に**intl_<言語コード>.arb**ファイルを用意します。

:::note info
arbファイルは、言語によってコードが変わります！
・日本語：intl_ja
・英語：intl_en
・中国語：intl_zh
:::

では日本語・英語・中国語のファイルを作成してみましょう！

### lib/l10n/intl_en.arb
```intl_en.arb
{
  "title": "Welcome",
  "welcome": "Welcome to our app!"
}
```

### lib/l10n/intl_ja.arb
```intl_ja.arb
{
  "title": "ようこそ",
  "welcome": "アプリへようこそ！"
}
```

### lib/l10n/intl_zh.arb
```intl_zh.arb
{
  "title": "欢迎",
  "welcome": "欢迎使用我们的应用！"
}
```

これらのファイルは、それぞれの言語に対応するテキストを定義します。
使用できる表現とそうでない表現もありそうです。

https://github.com/google/app-resource-bundle/wiki/ApplicationResourceBundleSpecification


## arbファイルを作成してビルドする

以下のコマンドをターミナルで実行し、
arbファイルをビルドしましょう！

```
flutter gen-l10n
```

arbファイルを作成後にビルドをすると、自動でファイルが生成されます。

![スクリーンショット 2024-10-20 19.34.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/945342/8e443bdf-e755-77ac-c7aa-1b796dff3ac4.png)

前章で作成したarbファイルの場合、英語版では下記のようなファイルが
自動で生成されます。

:::note warn
#### 注意！
arbファイルに不備があると、
クラッシュやエラーの原因になりますので注意！
:::

```app_localizations_ja.dart
import 'package:intl/intl.dart' as intl;

import 'app_localizations.dart';

// ignore_for_file: type=lint

/// The translations for English (`en`).
class AppLocalizationsEn extends AppLocalizations {
  AppLocalizationsEn([String locale = 'en']) : super(locale);

  @override
  String get title => 'Welcome';
}
```

## アプリに実装しよう！
これらの設定を反映させることで、言語切り替えが可能になります!
Flutterはデバイスの言語設定に基づいて、適切な言語リソースを自動的に選択します。

では実際に実装して動作確認してみましょう！

```main.dart
import 'package:flutter/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:intl/intl.dart';
import 'l10n/l10n.dart'; // l10nファイルをインポート

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      
      // 多言語化設定
      // ==============================================
      locale: Locale('en'), // デフォルト言語を英語に設定
      supportedLocales: L10n.all, // 対応する言語を設定
      localizationsDelegates: [
        AppLocalizations.delegate,
        GlobalMaterialLocalizations.delegate,
        GlobalWidgetsLocalizations.delegate,
        GlobalCupertinoLocalizations.delegate,
      ],
      // ==============================================
      
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(AppLocalizations.of(context)!.title),
      ),
      body: Center(
        // ここにTextで設定したファイルの内容を表示する
        child: Text(AppLocalizations.of(context)!.title),
      ),
    );
  }
}
```

### 動作結果(中国語)

![スクリーンショット 2024-10-20 19.42.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/945342/447a762a-45a2-5aa4-7897-0f67e10348d3.png)

### 動作結果(英語)
冒頭に貼りましたが一応！

![スクリーンショット 2024-10-20 19.09.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/945342/bf0d8b32-cd95-72ac-876f-d84aacb50840.png)

### 動作結果(日本語)

![スクリーンショット 2024-10-20 19.09.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/945342/1334fdb6-4989-7d2a-dbda-1765e0227b5e.png)

## まとめ
設定やライブラリのインストールはもちろん必要にはなりますが、
意外と簡単ではないでしょうか？

端末の設定によって表示する内容を簡単に変えられます。
日本語ユーザーのみならず、世界中の方が対象になるアプリを作っちゃいましょう！

この記事が参考になれば幸いです！

## 参考文献
https://zenn.dev/amuro/articles/27799da3afc40e