アプリを多言語化(ローカライゼーション)するには、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 Intl」
まずは、「Flutter Intl」プラグインの導入です。
インストール
「Flutter Intl」は、Android StudioのMarketplaceからインストールします。
メニューバーの[Android Studio]>[settings…]>[plugins]でダイアログを開いたら、検索バーに「intl」と入力(「Flutter Intl」ってちゃんと入力してもいいけど)すると、「Flutter Intl」が出てくるので、「Install」をクリックします。
インストール後、Android Studioを再起動するよう言われたら従います。
プラグインのインストールは、Android Studioへのインストールなので、一番最初の1回だけです。
プロジェクトごとに、インストール作業をする必要はありません。
初期化(イニシャライズ)
次は、「Flutter Intl」の初期化です。
ここからの作業は、Flutterのプロジェクトごとに必要な作業です。
多言語化するプロジェクトごとに実行します。
Android Studioのメニューバーから[Tools]>[Flutter Intl]>[Initialize for the Project]を実行します。
初期化では、Android Studio内部でコードが実行されます。
正常に初期化が終わると、Messages:にProcess finished with exit code 0
と表示されて止まります。
Flutterプロジェクトには[generated]と[l10n]フォルダが作成され、それぞれ必要なファイルが自動作成されています。
この時点では赤線のエラーが出ていますが、まだ作業途中なので、気にせずにそのまま「Get dependencies」をクリックして先へ進みます。
ここでも、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
flutter_localizations:
を入れた数秒後くらいに、自動で何かが実行されるかもしれないけど、Process finished with exit code 0
で止まっていれば、正常に動作しているので、大丈夫。
Pub getをクリックすると、[generated]フォルダの赤線のエラーが消えます。
初期化コードの実装
次は、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からネイティブコード編集アプリを起動する方法の詳細はこちら
Xcodeが起動したら[Runner]の中の[Info.plist]をクリックし、画面右側「Information Property List」の「+」で「Localizations」を追加します。
「Localizations」の初期状態は「Item 0」の「English」だけなので、ここに「Item 1」として「Japanese」を追加します。
Xcodeで設定した[Info.plist]は、FlutterプロジェクトのXMLファイルに反映されます。
ここまでで、多言語化のベースができました。
あとは、自分のアプリで表示したい各言語(英語、日本語など)の定義ファイルが必要ですが、この定義ファイルは、最初にすべてを定義しておくというより、アプリを実際に作っていく過程で追加しながら進めるのが現実的なのだと思います。
文字ファイル「.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]に、例として下記のように2つの文字列を定義します。
英語表記の定義ファイル
{
"appTitle": "Intl Test",
"homeMessage": "You have pushed the button this many times:"
}
行頭の"appTitle":
の部分がキーで、その後ろの"Intl Test"
が、スマホに実際に表示する文字列です。
入力するときに、行頭の2字下げや、:
の後ろのスペース挿入は、Android Studioが自動でやってくれるので、細かいことは気にせずに入力できます。
行末は,
(カンマ)で区切りますが、定義の最終行(ここでは"homeMessage": 〜
の行)には,
(カンマ)をつけてはいけません。
カンマが入ると赤線でエラー表示されます。
日本語ファイル「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]が作成されます。
キーの部分は英語(intl_en.arb)と同じ"appTitle":
にして、キーの後に続く表記文字が日本語の"intlのテスト"
となるよう対応させます。
"homeMessage":"ボタンを押した回数は:"
も同様です。
ここでも、最終行には,
(カンマ)はつけないので注意して。
日本語表記の定義ファイル
{
"appTitle": "Intlのテスト",
"homeMessage":"ボタンを押した回数は:"
}
これで、準備が終わりました。
あとは、Flutterのソースコードから呼び出して使います。
Flutterからの呼び出し方
ここでは、Flutterのカウントアップのサンプルプロジェクトの文字表記の部分を「.arb」の定義に従って表示してみます。
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,
),
],
),
),
では実際に実行して、表示を確認します。
まずは、スマホの設定が英語状態でデバッグしてみます。
デバッグ状態のままで、スマホの「設定(Setting)」で言語を「日本語」に変更します。
言語設定を日本語にして、アプリ画面に戻ると…
デバッグ途中で言語設定を変えて、アプリに戻ってくると、すぐに日本語の表示に切り替わりました。
次はiPhoneです。
Androidエミュレーターを終了して、iOSのシミュレーターを起動してデバッグします。
ここでも、デバッグ状態のままで、iPhoneの「設定(Setting)」から「日本語」に変更後、アプリ画面に戻ってみます。
iOSシミュレーターでも、英語・日本語の表示が切り替わることが確認できました。
ばんざ〜い!
「l10n」の読み方
「l10n」は「える てん えぬ」と読みます。
どうして「える てん えぬ」なの? と不思議に思っていたら「Flutter実践開発 ── iPhone/Android両対応アプリ開発のテクニック」の「4.2 アプリを日本語に対応させる」の項に数行の答えが出ていました。
「l10n」の「l(える)」は「Localization」の先頭文字の「L」。
「l10n」の「n(えぬ)」は「Localization」の末尾文字の「n」。
で、
「l10n」の「10」は「L」と「n」の間にあるアルファベットの個数が「10」ということらしいです。
こういう命名って、もしかしたらあるあるなのかも…
プラグインやパッケージを使うとき、読み方がわからないとちょっと気持ち悪いので、これも備忘録。
コメント