やりたいこと
今回やりたいのは、対応言語を複数セットした状態で、サポートしていない言語が端末に設定されていた場合にデフォルトの言語を設定することです。
やりたいこととしては、
- Flutterでは英語と日本語で多言語対応をする。
- 端末は言語と地域でそれぞれ設定できるので、言語優先で判別できるようにする。
ex.日本語設定で、地域設定がアメリカだった場合は日本語を表示させる。 - 日本語と英語以外の言語設定の場合は、一律英語を表示させる。
上記の対応をしようとしたのですが、対応言語を複数セットした状態で、デフォルトの言語を設定する方法が調べてもぱっと出てこなかったので記録として残しておきます。
実装手順
Flutterの多言語対応についての公式ドキュメントをみてみると、以下のように実装しましょうと書かれています。
return const MaterialApp(
title: 'Localizations Sample App',
localizationsDelegates: [
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
],
supportedLocales: [
Locale('en'), // English
Locale('ja'), // 日本語
],
home: MyHomePage(),
);
supportedLocales
に対応したい言語をセットすると、端末の言語設定で未対応言語が設定されている場合にすべて日本語で表示されてしまいました。
やりたいのはここをデフォルトで英語で表示すること。
色々と調べてみると、localeListResolutionCallback
というパラメータが準備されており、ここで設定ができそうでした。
localeListResolutionCallback
このコールバックは、アプリの起動時や、ユーザーがデバイスのロケールを変更したときに、アプリのロケールを選択する役割を担っています。
今回はロケールではなく、設定された言語で判別をしたかったので、以下のように実装してみました。
import 'dart:ui' as ui;
...
return const MaterialApp(
title: 'Localizations Sample App',
localizationsDelegates: [
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
],
supportedLocales: [
Locale('en'), // English
Locale('ja'), // 日本語
],
localeListResolutionCallback: (locales, supportedLocales) {
final currentLocale = ui.window.locale; // デバイスで設定されているロケールの取得
log('current locale language=${currentLocale.languageCode} device locales=$locales supported locales=$supportedLocales');
if (locales == null) {
return const Locale('en', 'US');
}
for (var locale in supportedLocales) {
// languageCodeで言語コードが取得できる
// supportedLocalesと一致すればそのまま返す、それ以外は英語を返す
if (currentLocale.languageCode == locale.languageCode) {
return locale;
}
}
return const Locale('en', 'US');
},
home: MyHomePage(),
);
ログを仕込んだ箇所では以下のように出力されていました。
言語設定では韓国語を設定し、地域設定ではアメリカをテスト的に設定しています。
current locale language=ko device locales=[ja_US, en_US, ko_US] supported locales=[en_US, ja_JP]
コールバックに入ってくるlocales
の値を見てみると(下記)、上記で設定したとおりに表記されていました。
device locales=[ja_US, en_US, ko_US]// 端末設定で追加された言語が入る
これは、端末側で追加されている言語がすべて表示されています。
アメリカ在住の日本人だとこのような組み合わせのパターンもありうると思い、端末の言語設定基準で表示を切り替える方針としました。ここも少し注意点かと思います。
結果としては、supported locales
に設定のない韓国語での言語設定が端末でなされていたので、Locale('en', 'US')
が返却され、スマホの画面上でも問題なく英語表記になったことを確認できました。
もちろん、言語設定を日本語にした場合には日本語が、英語設定にした場合には英語表記となることも確認できました。
最後に
以上で、Flutter多言語対応にて、未対応言語の場合にデフォルトの言語を設定する方法が実装できました。
私の理解不足で、ほかに方法があるのかもしれません。
あくまでも個人用の記録として残しておきたいと思います。
参考
https://docs.flutter.dev/development/accessibility-and-localization/internationalization
https://api.flutter.dev/flutter/material/MaterialApp/localeListResolutionCallback.html