Flutterアプリ多言語対応にVSCode拡張Flutter Intlを使う
2021.8
趣味的開発のFlutterアプリの多言語対応にVS Code拡張Flutter Intlを使い便利でした。
よく分かってなくて雰囲気なところは事実を記載していきます。
なお、最後に宣伝があります。
VS Code拡張Flutter Intlとは
多言語対応の核にflutter_localizationsパッケージを使った上で、翻訳テキストを言語別のファイルで管理してそれを呼び出すコードを自動生成する仕組みを提供してもらえます。
Flutter Intlの使い方
1. VS CodeにFlutter Intl拡張をインストールします。
2. Flutter Intlの初期設定を行います。
コマンドパレットでFlutter Intl: Initialize
を実行します。
以下のファイルが生成されます。
-
lib/l10n/intl_en.arb
がデフォルトの翻訳テキストを管理するファイル(形式はApplication Resource Bundle)です。この記事では翻訳テキスト管理ファイルと呼ぶことにします。enなのでデフォルトの翻訳言語は英語です。 -
lib/generated/
配下のdartファイルは翻訳テキストを呼び出すコードです。自動生成され、編集はしません。- 赤くなっていますが次の3.で対処します。
3. Flutter_localizationsパッケージを依存関係に追加します。
pubspec.yaml
のdependencies
にflutter_localizations
を追加します。
dependencies:
+ flutter_localizations:
+ sdk: flutter
# 他のパッケージは省略
- 2.で生成ファイルが赤くなっていたのはflutter_localizationsへの依存が原因なので解消されます。
- 自動的に
flutter_intl
の設定がpubspec.yaml
に追加されます。
# 自動的に追加される
flutter_intl:
enabled: true
4. デフォルトの翻訳テキストを定義します。
デフォルトの翻訳テキスト管理ファイルであるlib/l10n/intl_en.arb
に、翻訳テキストを定義します。
デフォルトの翻訳言語は英語なので例えば以下のように記入します。
{
+ "hello": "Hello World."
}
- 変数名が翻訳テキストの名称、値が翻訳テキストそのものです。
-
lib/l10n/intl_en.arb
を保存すると、lib/generated/
配下のdartファイルが自動的に再生成されます。
5. 翻訳言語を追加します。
コマンドパレットでFlutter Intl: Add locale
を実行します。
続いてロケールを入力します。ここでは日本(語)を表すja_JP
を入力します。
以下のように日本語テキストの管理ファイルlib/l10n/intl_ja_JP.arb
が生成されます。
-
lib/generated/
配下のdartファイルも追加・更新されていますが、編集はしません。
英語の翻訳テキストに対応する日本語をlib/l10n/intl_ja_JP.arb
に定義します。
{
+ "hello": "こんにちは世界。"
}
-
lib/l10n/intl_ja_JP.arb
を保存すると、lib/generated/
配下のdartファイルが自動的に再生成されます。
6. 翻訳テキストをコードから使用するための設定を行います。
MaterialApp
の引数localizationsDelegates
とsupportedLocales
に翻訳テキストをコードから使用するための設定を行います。
// 以下のimportを追加
+ import 'package:flutter_localizations/flutter_localizations.dart';
+ import 'generated/l10n.dart';
return MaterialApp(
+ localizationsDelegates: [
+ // 翻訳テキストを呼び出す"S"クラスのデリゲートを登録
+ S.delegate,
+ // よく分かっていませんがこれらも登録
+ GlobalMaterialLocalizations.delegate,
+ GlobalWidgetsLocalizations.delegate,
+ GlobalCupertinoLocalizations.delegate,
+ ],
+ // 翻訳言語の種類を設定
+ supportedLocales: S.delegate.supportedLocales,
// 他の引数は省略
);
- "S"クラスは
lib/generated/l10n.dart
に記述されています。 -
S.delegate.supportedLocales
で取得できる翻訳言語の種類は、翻訳テキスト管理ファイルの種類と自動的に対応します。
例えばintl_en.arb
とintl_ja_JP.arb
があるなら[Locale('en'), Locale('ja', 'JP')]
(相当)になります。
7. 翻訳テキストをコードから使用します。
翻訳テキストはS.of(context).翻訳テキストの変数名
というプロパティで使用します。
端末のロケールと一致する翻訳テキスト管理ファイルの翻訳テキストを取得できます。
class MyApp extends StatelessWidget {
Widget build(BuildContext context) {
return MaterialApp(
// 他の引数は省略
home: MyPage(),
);
}
}
class MyPage extends StatelessWidget {
Widget build(BuildContext context) {
// 翻訳テキスト管理ファイルの変数名'hello'のテキストを取得
+ String message = S.of(context).hello;
return Scaffold(
body: Text(message),
);
}
}
-
S.of(context)
のプロパティ名にlib/l10n/intl_en.arb
で定義した翻訳テキストの名称を使用します。 - "S"クラスはWidgetツリーにおけるMaterialAppの
home:
に指定したWidget以下で使用できます。
Tips
翻訳テキストを動的に変更する
翻訳テキストは静的に定義するだけでなく、動的に変更する機能があります。
{
"hello": "Hello World.",
+ "hellosomething": "Hello {name}.",
+ "hellovariation": "{name, select, morning {Good morning.} daytime {Good afternoon.} night {Good evening.} other {{name}.}}"
}
-
{name}
はプレースホルダーです。以下のように使います。
S.of(context).hellosomething('sky'); // "Hello sky."
-
name, select, ... {...}
という書式でコード側から翻訳テキストを切り替えられます。以下のように使います。
S.of(context).hellovariation('morning'); // "Good morning."
S.of(context).hellovariation('daytime'); // "Good afternoon."
S.of(context).hellovariation('night'); // "Good evening."
S.of(context).hellovariation('midnight'); // "midnight."
書式は他にもあると思います。
翻訳テキスト管理ファイルは地域コードごとに作成した方が安心
例えば翻訳テキスト管理ファイルとしてintl_es.arb
とintl_es_ES.arb
があり、端末のロケールがes_USだったとき、intl_es.arb
が使われるのかはよく分かりません。手元のAndroid端末で試すと使われそうなのですが、外国のAndroid端末は多様な環境があるはずで、環境依存で挙動が異なる可能性を排除するのは怖いです。翻訳テキスト管理ファイルを地域コードごとに作成して精神的な安心を得ています。
- 端末のロケールが地域コード無しの言語コードのみな場合もあるような気がしているので、
intl_ja.arb
といった言語コードのみのファイルも用意しています。
宣伝
Twitterトレンドワードを時系列チャートで見られます。
Discussion