🍸

Flutterアプリ多言語対応にVSCode拡張Flutter Intlを使う

2021/08/09に公開

2021.8
趣味的開発のFlutterアプリの多言語対応にVS Code拡張Flutter Intlを使い便利でした。
よく分かってなくて雰囲気なところは事実を記載していきます。
なお、最後に宣伝があります。

VS Code拡張Flutter Intlとは

多言語対応の核にflutter_localizationsパッケージを使った上で、翻訳テキストを言語別のファイルで管理してそれを呼び出すコードを自動生成する仕組みを提供してもらえます。
https://marketplace.visualstudio.com/items?itemName=localizely.flutter-intl

Flutter Intlの使い方

1. VS CodeにFlutter Intl拡張をインストールします。

VS CodeのFlutter Intl拡張

2. Flutter Intlの初期設定を行います。

コマンドパレットでFlutter Intl: Initializeを実行します。
コマンドパレット
以下のファイルが生成されます。
Initialize

  • lib/l10n/intl_en.arbがデフォルトの翻訳テキストを管理するファイル(形式はApplication Resource Bundle)です。この記事では翻訳テキスト管理ファイルと呼ぶことにします。enなのでデフォルトの翻訳言語は英語です。
  • lib/generated/配下のdartファイルは翻訳テキストを呼び出すコードです。自動生成され、編集はしません。
    • 赤くなっていますが次の3.で対処します。

3. Flutter_localizationsパッケージを依存関係に追加します。

pubspec.yamldependenciesflutter_localizationsを追加します。

pubspec.yaml
dependencies:
+ flutter_localizations:
+   sdk: flutter
  # 他のパッケージは省略
  • 2.で生成ファイルが赤くなっていたのはflutter_localizationsへの依存が原因なので解消されます。
  • 自動的にflutter_intlの設定がpubspec.yamlに追加されます。
pubspec.yaml
# 自動的に追加される
flutter_intl:
  enabled: true

4. デフォルトの翻訳テキストを定義します。

デフォルトの翻訳テキスト管理ファイルであるlib/l10n/intl_en.arbに、翻訳テキストを定義します。
デフォルトの翻訳言語は英語なので例えば以下のように記入します。

lib/l10n/intl_en.arb
{
+ "hello": "Hello World."
}
  • 変数名が翻訳テキストの名称、値が翻訳テキストそのものです。
  • lib/l10n/intl_en.arbを保存すると、lib/generated/配下のdartファイルが自動的に再生成されます。

5. 翻訳言語を追加します。

コマンドパレットでFlutter Intl: Add localeを実行します。
Add locale

続いてロケールを入力します。ここでは日本(語)を表すja_JPを入力します。
ロケールja_JP

以下のように日本語テキストの管理ファイルlib/l10n/intl_ja_JP.arbが生成されます。
Add locale ja_JP

  • lib/generated/配下のdartファイルも追加・更新されていますが、編集はしません。

英語の翻訳テキストに対応する日本語をlib/l10n/intl_ja_JP.arbに定義します。

lib/l10n/intl_ja_JP.arb
{
+ "hello": "こんにちは世界。"
}
  • lib/l10n/intl_ja_JP.arbを保存すると、lib/generated/配下のdartファイルが自動的に再生成されます。

6. 翻訳テキストをコードから使用するための設定を行います。

MaterialAppの引数localizationsDelegatessupportedLocalesに翻訳テキストをコードから使用するための設定を行います。

// 以下の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.arbintl_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

翻訳テキストを動的に変更する

翻訳テキストは静的に定義するだけでなく、動的に変更する機能があります。

lib/l10n/intl_en.arb
{
   "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.arbintl_es_ES.arbがあり、端末のロケールがes_USだったとき、intl_es.arbが使われるのかはよく分かりません。手元のAndroid端末で試すと使われそうなのですが、外国のAndroid端末は多様な環境があるはずで、環境依存で挙動が異なる可能性を排除するのは怖いです。翻訳テキスト管理ファイルを地域コードごとに作成して精神的な安心を得ています。
地域ごとの翻訳テキスト管理ファイル

  • 端末のロケールが地域コード無しの言語コードのみな場合もあるような気がしているので、intl_ja.arbといった言語コードのみのファイルも用意しています。

宣伝

https://play.google.com/store/apps/details?id=com.qcha.trendschartontwitter
Twitterトレンドワードを時系列チャートで見られます。

Discussion