Flutterアプリを多言語化する
Published on May 20, 2020
Flutterアプリを多言語化する方法についての自分メモ
基本的にFlutter公式Documentに沿って。
対応言語は英語、日本語。
intlパッケージ導入版で進めます。
packageの追加
pubspec.yaml
dependencies:
flutter:
sdk: flutter
flutter_localizations: sdk: flutter
dev_dependencies:
flutter_test:
sdk: flutter
intl_translation: ^0.17.09
intl_translation: ^0.17.10
が最新ですが、下記エラーが出るため0.17.09
を導入します。
Because intl_translation >=0.17.10 depends on petitparser ^3.0.0 and every version of flutter_test from sdk depends on petitparser 2.4.0, intl_translation >=0.17.10 is incompatible with flutter_test from sdk.
多言語化用のクラスを作成
l10n
フォルダを作成し、l10n.dart
にクラスを実装します。
lib/l10n/l10n.dart
import 'package:flutter/widgets.dart';
import 'package:intl/intl.dart';
import 'messages_all.dart';
class L10n {
L10n(this.localeName);
static Future<L10n> load(Locale locale) {
final name =
locale.countryCode.isEmpty ? locale.languageCode : locale.toString();
final localeName = Intl.canonicalizedLocale(name);
return initializeMessages(localeName).then((_) {
return L10n(localeName);
});
}
static L10n of(BuildContext context) {
return Localizations.of<L10n>(context, L10n);
}
final String localeName;
String get title {
return Intl.message(
'Hello World',
name: 'title',
desc: 'Title for the Demo application',
locale: localeName,
);
}
}
class L10nDelegate extends LocalizationsDelegate<L10n> {
const L10nDelegate();
bool isSupported(Locale locale) => ['en', 'ja'].contains(locale.languageCode);
Future<L10n> load(Locale locale) => L10n.load(locale);
bool shouldReload(L10nDelegate old) => false;
}
initializeMessages
の部分でエラーが出ますが、次で解消します。
messages_all.dartの生成
terminal
$ flutter pub run intl_translation:extract_to_arb \
--locale=messages \
--output-dir=lib/l10n \
lib/l10n/l10n.dart
intl_messages.arb
が生成されます。
続いて下記コマンドを実行。
terminal
$ flutter pub run intl_translation:generate_from_arb \
--output-dir=lib/l10n --no-use-deferred-loading \
lib/l10n/l10n.dart lib/l10n/intl_*.arb
messages_all.dart
が生成されます。
ここまでで基本的な前準備が完了です。
アプリを多言語化
main.dart
import 'package:flutter_localizations/flutter_localizations.dart';
MaterialApp(
localizationsDelegates: [
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
const L10nDelegate(),
],
supportedLocales: const [
Locale('en'), // English
Locale('ja'), // Japanese
],
// ...
)
Global〜というdelegateは、Flutter公式のWidgetの多言語化用。
GlobalCupertinoLocalizationsは、CupertinoWidget使ってなければ不要だと思う。
各言語用のarbファイルを作成
生成されたintl_messages.arb
をベースに、intl_en.arb
とintl_ja.arb
を生成します。
lib/l10n/intl_en.arb
{
"@@locale": "en",
"title": "Hello World"
}
lib/l10n/intl_ja.arb
{
"@@locale": "ja",
"title": "こんにちは世界"
}
最終行末尾の ,
を入れるとエラーが出たので削除。
再度下記のコマンドを実行。
terminal
$ flutter pub run intl_translation:generate_from_arb \
--output-dir=lib/l10n --no-use-deferred-loading \
lib/l10n/l10n.dart lib/l10n/intl_*.arb
これで、下記ファイルが自動生成されます。
・messages_all.dart
・messages_en.dart
・messages_ja.dart
・messages_messages.dart
widgetでの呼び出し方法
以下のような形で呼び出せます。
Text(L10n.of(context).setting)
XcodeのLocalizations追加
iOSの言語設定をFlutterアプリに適用するにはXcodeでLocalizationsを追加する必要があります。
用語を追加したい時
l10n.dart
に新たに追記して
String get setting {
return Intl.message(
'Setting',
name: 'setting',
desc: 'Setting',
locale: localeName,
);
}
各言語ファイルにも追記します。
lib/l10n/intl_en.arb
{
"@@locale": "en",
"title": "Hello World",
"setting": "Setting",}
lib/l10n/intl_ja.arb
{
"@@locale": "ja",
"title": "こんにちは世界",
"setting": "設定",}
用語を追加したら、下記のようなスクリプトを用意しておいて実行します。
update_l10n.sh
#!/bin/sh
BLUE='\033[0;34m'
NC='\033[0m'
echo "${BLUE}==>1. Extract to arb${NC}"
flutter pub run intl_translation:extract_to_arb \
--locale=messages \
--output-dir=lib/l10n \
lib/l10n/l10n.dart
echo "${BLUE}==>2. Generate dart file${NC}"
flutter pub run intl_translation:generate_from_arb \
--output-dir=lib/l10n --no-use-deferred-loading \
lib/l10n/l10n.dart lib/l10n/intl_*.arb
これで用語追加完了です。
Locale情報の取得
現在のLocaleはこんな感じで取得できる。
Locale myLocale = Localizations.localeOf(context);
参考URL
If you like it, share it!