Flutter の多言語対応(Intl)
Flutter で多言語対応した。
公式ドキュメントでもよく説明されていると思うし、 flutter.dev
こちらの mono さんの記事もすごく参考になる。
Dart/Flutter での多言語対応あれこれ - Flutter 🇯🇵 - Medium
今のところ DateFormat や NumberFormat は不要なので、文言をロケールに合わせて変更する部分だけ行った。
目次
パッケージのインストール
pubspec.yaml に追加。
dependencies: flutter: sdk: flutter flutter_localizations: sdk: flutter flutter_cupertino_localizations: ^1.0.1
flutter_cupertino_localizations は iOS でちゃんと動作させたいなら入れなさい、とのこと。
追記したら flutter pub get
を実行、もしくはAndroid Studio なら、Packages get をクリック。
MaterialApp修正
import 'package:flutter_localizations/flutter_localizations.dart'; import 'package:flutter_cupertino_localizations/flutter_cupertino_localizations.dart'; MaterialApp( localizationsDelegates: [ // ... app-specific localization delegate[s] here GlobalMaterialLocalizations.delegate, GlobalWidgetsLocalizations.delegate, GlobalCupertinoLocalizations.delegate, ], supportedLocales: [ const Locale('en'), // English const Locale('ja'), // Japanese // ... other locales the app supports ], // ... )
localizationsDelegates
ローカライズした value を使うためのファクトリを指定する。
- GlobalMaterialLocalizations.delegate
文字などの文言や他の MaterialApp コンポーネントようライブラリ - GlobalWidgetsLocalizations.delegate
文字列の方向(英語は左から右、アラビア語は右から左、みたいな)を定義するためのライブラリ
ということなのでおまじない的に両方入れておけばいいのかな。アラビア語とか対応しない限りは GlobalWidgetsLocalizations.delegate は無くてもいいのかはわからない。(試してない)
supportedLocales
アプリが対応する言語のロケールを指定する。
中国の繁体字/簡体字みたいに方言?がある場合はLocale.fromSubtags(languageCode: 'zh')
という感じでできるらしいが、今回は日本語と英語のみなので省略。
ローカライズリソースの定義
class DemoLocalizations { DemoLocalizations(this.localeName); static Future<DemoLocalizations> load(Locale locale) { final String name = locale.countryCode.isEmpty ? locale.languageCode : locale.toString(); final String localeName = Intl.canonicalizedLocale(name); return initializeMessages(localeName).then((_) { return DemoLocalizations(localeName); }); } static DemoLocalizations of(BuildContext context) { return Localizations.of<DemoLocalizations>(context, DemoLocalizations); } final String localeName; String get hello { return Intl.message( 'こんにちは', name: 'hello', locale: localeName, ); } }
initializeMessages() がローカライズされたメッセージカタログで読み込み、intl パッケージが インポートする。
Intl.message() でそれらを読み込んで返している。
という流れ。
メッセージカタログは、後述する intl のツールで作成できる。
多言語対応(メッセージカタログの作成)
intl のツールを利用する。
arb ファイル作成
flutter pub run intl_translation:extract_to_arb --output-dir=lib/l10n lib/main.dart
main.dart 内にある Intl.message() ごとに定義を作成できる。
lib/l10n の下に intl_messages.arb という JSON ファイルが出力される。
複数言語対応するときは、この arb ファイルをベースに intl_ja.arb や intl_en.arb を作成する。
dart ファイル作成
flutter pub run intl_translation:generate_from_arb \ --output-dir=lib/l10n --no-use-deferred-loading \ lib/main.dart lib/l10n/intl_*.arb
上記で作成した arb ファイルごとに、 intl_XXX_all.dart が作成される。
この dart ファイルの中身がロケールに応じて使われる。
使ってみる
print(DemoLocalizations.of(context).hello);
みたいにするだけ。
デフォルトロケールが日本と想定して、
こんにちは
ロケールを変更したい場合は、 DemoLocalizations.load(Locale('en'));
としてやる。
DemoLocalizations.load(Locale('en'));
print(DemoLocalizations.of(context).hello);
hello
その他
とりあえず公式ページにあるコードをサンプルとして掲載。
後日 git にサンプルあげる。