旧サイトから記事の移行中です

Flutterの多言語化はIntlプラグインとflutter_localizationsパッケージの併用がベスト

アプリを多言語化(ローカライゼーション)するには、Flutter公式が推奨する「flutter_localizations」というパッケージが一般的です。

でも、このパッケージだけでは手順が多くなるので、「Flutter Intl」というプラグインと合わせて使うのがオススメです。

この記事では、プラグインの「Flutter Intl」と、パッケージの「flutter_localizations」の2つのツールのインストールと、「.arb」ファイルの作成、Flutterコードから表示文字列の呼び出すコードの書き方まで解説します。

動作確認バージョン
  • Flutter: 3.27.1
  • Dart: 3.6.0
  • Android Studio: Koala (2024.1.1)
  • Flutter Intl: 1.18.5-2023.2
  • flutter_localizations:

pub.devには「flutter_localization」という、末尾に「s」のない名称のよく似たパッケージがあります。

この「sなしflutter_localization」は、Flutter公式の「flutter_localizations」をヒントにして作られたという別物なので、この2つは実装方法などが全く違います。

pub.devの「flutter_localization」に記載の注意書き

Flutter Localization is a package use for in-app localization with map data. More easier and faster to implement and inspired by the flutter_localizations itself.

https://pub.dev/packages/flutter_localization
目次

「Flutter Intl」

まずは、「Flutter Intl」プラグインの導入です。

インストール

「Flutter Intl」は、Android StudioのMarketplaceからインストールします。

メニューバーの[Android Studio]>[settings…]>[plugins]でダイアログを開いたら、検索バーに「intl」と入力(「Flutter Intl」ってちゃんと入力してもいいけど)すると、「Flutter Intl」が出てくるので、「Install」をクリックします。

Android Studioの「Settings...」のメニューを実行する画面
Android Studioのメニューから「Settings…」を選ぶ
Android Studioのマーケットプレイスで「Flutter Intl」プラグインをインストールする画面

インストール後、Android Studioを再起動するよう言われたら従います。

プラグインのインストールは、Android Studioへのインストールなので、一番最初の1回だけです。
プロジェクトごとに、インストール作業をする必要はありません。

初期化(イニシャライズ)

次は、「Flutter Intl」の初期化です。

ここからの作業は、Flutterのプロジェクトごとに必要な作業です。
多言語化するプロジェクトごとに実行します。

Android Studioのメニューバーから[Tools]>[Flutter Intl]>[Initialize for the Project]を実行します。

Android Studioの「Flutter Intl」プラグインのイニシャライズするメニュー項目
「Flutter Intl」をインストールすると「Tools」に「Flutter Intl」が現れる

初期化では、Android Studio内部でコードが実行されます。

正常に初期化が終わると、Messages:にProcess finished with exit code 0と表示されて止まります。

Flutterプロジェクトには[generated]と[l10n]フォルダが作成され、それぞれ必要なファイルが自動作成されています。

この時点では赤線のエラーが出ていますが、まだ作業途中なので、気にせずにそのまま「Get dependencies」をクリックして先へ進みます。

Android Studioの「Flutter Intl」をイニシャライズしたあとのフォルダ構成。フォルダにはエラーを示す赤い波線が表示されているが、この時点ではこのままでOK

ここでも、Messages:に〜〜 exit code 0と最後に表示されるので、正常に終了したことを確認します。

自動作成された[generated]フォルダの中身は、手作業で修正していはいけません。

「flutter_localizations」

インストール

プラグインの次に、「flutter_localizations」というパッケージをインストールします。

この「flutter_localizations」パッケージだけで多言語化(ローカライズ)することもできますが、自力でやるのはかなり面倒くさいので、先にインストールしたFlutter Intlプラグインと合わせて使います。

[pubspec.yaml]のdependencies:に、flutter_localizations:の2行を次のように追加します。
flutter:の次あたりに入れます。)

dependencies:
  flutter:
    sdk: flutter
  flutter_localizations:
    sdk: flutter
Android Studioの「pubspec.yaml」ファイルに「flutter_localizations:」を入力した画面。 入力すると、自動でgeneratorが動いて、「〜code 0」で止まる。
generatorが動いて「〜code 0」で止まれば正常

flutter_localizations:を入れた数秒後くらいに、自動で何かが実行されるかもしれないけど、Process finished with exit code 0で止まっていれば、正常に動作しているので、大丈夫。

Pub getをクリックすると、[generated]フォルダの赤線のエラーが消えます。

pub getをクリックして、[generated]フォルダの赤線のエラーが消えた状態
「Pub get」も忘れずに実行する

初期化コードの実装

次は、FlutterのMaterialAppに、下記コードを追加します。

import 'package:flutter/material.dart';
import 'generated/l10n.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'localizations test',
      localizationsDelegates: [
        S.delegate
        GlobalMaterialLocalizations.delegate,
        GlobalCupertinoLocalizations.delegate,
        GlobalWidgetsLocalizations.delegate,
      ],
      supportedLocales: S.delegate.supportedLocales,

17行目と22行目のS.のSは、[lib]/[generated]フォルダの[l10n.dart]で定義されているclassなので、import 'generated/l10n.dart';を冒頭でインポートします。

18〜20行目のGlobal〜〜Localizationsも、import 'package:flutter_localizations/flutter_localizations.dart';をインポートしてエラーを解消します。

iOS端末の多言語化の設定(Xcode)

MacでFlutter開発をしている場合は、iOSネイティブアプリとしての設定が必要です。

「iOSネイティブの設定はしなくてもいい」って言っている人もいて、実際、私のプロジェクトでも何もせずにiPhoneシミュレーターで動いたんだけど…

でも公式サイトには、「Localizing for iOS: Updating the iOS app bundle」として掲載されているので、やっとくほうがいいと思います。

iOSネイティブの設定は、[iOS]/[Runner]フォルダの中の[Info.plist]ファイルです。

[Info.plist]は、FlutterプロジェクトのXML形式のままだと、最初はタグ名など入力ルールがわからなくて編集できないので、Xcodeで編集します。

まずは、Flutterプロジェクトから[Info.plist]を開いてから、画面上部の「Open iOS/macOS module in Xcode」をクリックしてXcodeを起動します。
Xcodeの起動には少し時間がかかるかも。

Android Studioからネイティブコード編集アプリを起動する方法の詳細はこちら

Flutterプロジェクトで「Info.plist」を開いたあと、iOSネイティブの設定をするために、画面上部の「Open iOS/macOS module in Xcode」をクリックする画面の図。
[Info.plist]をAndroid Studioで開いてからXcodeを起動

Xcodeが起動したら[Runner]の中の[Info.plist]をクリックし、画面右側「Information Property List」の「+」で「Localizations」を追加します。

iOSの多言語設定するため、XcodeでInfo.plistを開いて、Information Property ListでLocalizationsを追加する図。
「Information Property List」に「Localizations」を追加

「Localizations」の初期状態は「Item 0」の「English」だけなので、ここに「Item 1」として「Japanese」を追加します。

iOSの多言語設定するため、XcodeでLocalizationsの設定をする図。 Item0のEnglishはそのまま残して、Item1にJapaneseを追加する。
「item0」はそのまま残して、「item1」を「Japanese」にする

Xcodeで設定した[Info.plist]は、FlutterプロジェクトのXMLファイルに反映されます。

XcodeでiOSネイティブの多言語設定したあと、Flutterプロジェクトに戻って、Info.plistを表示している図。 Xcodeで編集した内容がきちんと反映されている。
Flutterプロジェクトの[Info.plist]に「CFBundleLocalizations」が追加された

ここまでで、多言語化のベースができました。

あとは、自分のアプリで表示したい各言語(英語、日本語など)の定義ファイルが必要ですが、この定義ファイルは、最初にすべてを定義しておくというより、アプリを実際に作っていく過程で追加しながら進めるのが現実的なのだと思います。

文字ファイル「.arb」の作成

ここからは、作成するアプリ画面に表示する文字の定義ファイル(文字リソース)を作ります。

定義ファイルは、1言語1ファイルのテキストファイルとして作成します。
拡張子は「arb」です。

arb(Application Resource Bundle Specification)は、JSON形式で記述します。

JSON形式には、「データ全体を{}で囲む」とか「行頭は2字下げ」などいくつかのルールがあります。

Android Studioで直接ARBファイルを入力する場合は、自動で「2字下げ」や「スペース挿入」などコード補完してくれるので、記述ルールはあまり気にしなくても大丈夫です。

英語ファイル「intl_en.arb」

デフォルトでは、中身がカラっぽの英語の定義ファイル[intl_en.arb]だけは作成されているので、まずはこの英語の「.arb」ファイルに定義を入力していきます。

英語表記の定義ファイル「intl_en.arb」の初期状態は{}だけが入力されている。
デフォルトでは[intl_en.arb]の中身は空っぽ

この[intl_en.arb]に、例として下記のように2つの文字列を定義します。

英語表記の定義ファイル

{
  "appTitle": "Intl Test",
  "homeMessage": "You have pushed the button this many times:"
}

行頭の"appTitle":の部分がキーで、その後ろの"Intl Test"が、スマホに実際に表示する文字列です。

入力するときに、行頭の2字下げや、:の後ろのスペース挿入は、Android Studioが自動でやってくれるので、細かいことは気にせずに入力できます。

行末は,(カンマ)で区切りますが、定義の最終行(ここでは"homeMessage": 〜の行)には,(カンマ)をつけてはいけません。

カンマが入ると赤線でエラー表示されます。

Flutterプロジェクトで多言語表記するときの英語の文字リソース「intl_en.arb」に、JSON形式で定義を入力した図。
.arbファイルを編集するたびにプラグインが勝手に動いて、「Messages:」のエリアに処理内容が表示される

日本語ファイル「intl_ja.arb」

英語以外の.arbを作成するには、Android Studioのメニューバーから[Tools]>[Flutter intl]>[Add locale]を実行します。

ここでは日本語のリソースファイルを作りたいので、locale(ロケール)入力のダイアログに「ja」と入力します。

ロケール(Locale)とは、「ISO 639-1」という規格で言語ごとに決められている登録コードです。

「ISO 639」には、追版が「-1」「-2/T」「-3」などいくつかあります。
その中から「ISO 639-1」を使います。

すると、[intl_en.arb]と並んで[intl_ja.arb]が作成されます。

Android Studioのメニューから「Tools」>「Flutter Intl」>「Add Locale」を実行し、表示された「Add New Locale」のダイアログで「ja」と入力している図。これで、日本語のARBファイルが作成される。
Android Studioのメニューから日本語の定義ファイルを作る

キーの部分は英語(intl_en.arb)と同じ"appTitle":にして、キーの後に続く表記文字が日本語の"intlのテスト"となるよう対応させます。

"homeMessage":"ボタンを押した回数は:"も同様です。

ここでも、最終行には,(カンマ)はつけないので注意して。

日本語表記の定義ファイル

{
  "appTitle": "Intlのテスト",
  "homeMessage":"ボタンを押した回数は:"
}

これで、準備が終わりました。
あとは、Flutterのソースコードから呼び出して使います。

Flutterからの呼び出し方

ここでは、Flutterのカウントアップのサンプルプロジェクトの文字表記の部分を「.arb」の定義に従って表示してみます。

Flutterの多言語表記で、ARBファイルの設定を呼び出すコード。
AppBarのタイトルと、数字の上に表示されるテキストを多言語化

Flutterサンプルコードの[main.dart]の2カ所を、多言語表示で切り替えます。

呼び出し方はS.of(context).appTitleです。Textウィジェットで囲んでいます。

appBar:部分を抜粋

      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: Text(S.of(context).appTitle),
      ),

body:部分を抜粋

      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(S.of(context).homeMessage),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.headlineMedium,
            ),
          ],
        ),
      ),

では実際に実行して、表示を確認します。

まずは、スマホの設定が英語状態でデバッグしてみます。

Androidスマホの多言語表記で「英語」を表示している図。
[intl_en.arb]に基づいた英語表記

デバッグ状態のままで、スマホの「設定(Setting)」で言語を「日本語」に変更します。

Androidスマホの言語設定を、英語から日本語に変更している図。

言語設定を日本語にして、アプリ画面に戻ると…

Androidスマホの多言語表記で「日本語」を表示している図。
[intl_ja.arb]に基づいた日本語表記

デバッグ途中で言語設定を変えて、アプリに戻ってくると、すぐに日本語の表示に切り替わりました。

次はiPhoneです。
Androidエミュレーターを終了して、iOSのシミュレーターを起動してデバッグします。

iPhoneの多言語表記で「英語」を表示している図。

ここでも、デバッグ状態のままで、iPhoneの「設定(Setting)」から「日本語」に変更後、アプリ画面に戻ってみます。

iPhoneのSettingsで、言語設定を日本語に変更している図。
iPhoneの多言語表記で「日本語」を表示している図。

iOSシミュレーターでも、英語・日本語の表示が切り替わることが確認できました。
ばんざ〜い!

「l10n」の読み方

「l10n」は「える てん えぬ」と読みます。

どうして「える てん えぬ」なの? と不思議に思っていたら「Flutter実践開発 ── iPhone/Android両対応アプリ開発のテクニック」の「4.2 アプリを日本語に対応させる」の項に数行の答えが出ていました。

「l10n」の「l(える)」は「Localization」の先頭文字の「L」。
「l10n」の「n(えぬ)」は「Localization」の末尾文字の「n」。
で、
「l10n」の「10」は「L」と「n」の間にあるアルファベットの個数が「10」ということらしいです。

こういう命名って、もしかしたらあるあるなのかも…

プラグインやパッケージを使うとき、読み方がわからないとちょっと気持ち悪いので、これも備忘録。

よかったらシェアしてね!
  • URLをコピーしました!

コメント

コメントする

目次