IntlのFlutterでの多言語対応について。
Intlの例えばDateFormatの書式指定をきちんと日本語対応したものにしたいなど、Flutterとどのように連携させればいいのかちょっと記述する。
Intlについて
Flutter/Dartの国際化およびローカリゼーション機能を提供しているパッケージで、Localeクラスを指定することにより、多言語メッセージへの対応、数値、日付等の書式設定ができる機能を持っている。
![](https://pub.dev/static/hash-m8galh30/img/pub-dev-icon-cover-image.png)
Localeを特に指定しない場合は「en_US」が設定されているものとして処理されるため、他の言語を使用する場合は、正しく設定もしくは利用する必要がある。
使用される言語設定の方法
基本的に、DateFormatやNumberFormatの書式指定クラスにはパラメータとしてLocaleを指定することができるようになっている。
また指定しない場合は「Intl.defaultLocale」のSTATICプロパティに設定されている言語設定が使われる。
FlutterでIntlの言語指定
対応方法としては大まかに2種類ある。
- MaterialLocalizationsを利用する方法
- Intl.defaultLocaleを変更する方法
MaterialLocalizationsを利用する方法
こちらはIntlを直接利用する方法ではないのだけど、DateFormatのいくつかの書式設定とNumberFormat. decimalPatternがメソッドとして用意されていて、それぞれがアプリケーション内で使用する場合、利用する言語環境のものが使用できるようになっている。
以下がそれの対応表。
MaterialLocalizations | Intl |
formatYear | DateFormat.y |
formatCompactDate | DateFormat.yMD |
formatShortDate | DateFormat.yMMMD |
formatMediumDate | DateFormat.MMMEd |
formatFullDate | DateFormat.yMMMMEEEEd |
formatMonthYear | DateFormat.yMMMM |
formatShortMonthDay | DateFormat.MMMd |
formatDecimal | NumberFormat. decimalPattern |
ウィジェットのビルド時に、MaterialLocalizations.of(context)でインスタンスを取り出し、該当するメソッドを利用する。特殊な書式でなければこれでいいのではないかと思う。
これを使用するには、MaterialAppのlocalizationsDelegatesにGlobalMaterialLocalizations.delegateを追加登録する必要がある。
Intl.defaultLocaleを変更する方法
Androidの言語設定で、英語、日本語等に変更した場合、Intl.defaultLocaleが何もしなくても連動してくれればいいのだけども、そういうことはなく、自分で実装しなければいけない。
ただIntl.defaultLocaleを変更すれば、DateFormatのフォーマッタをそのまま呼び出し利用することができるので便利だとは思う。
具体的な実装としてはIntl.defaultLocaleを変更するLocalizationsDelegateを作り、それをMaterialAppのlocalizationsDelegatesに指定する。
それが以下のクラス。
class IntlDelegate extends LocalizationsDelegate {
@override
bool isSupported(Locale locale) {
return true;
}
@override
Future load(Locale locale) {
Intl.defaultLocale = locale.toString();
return Future(() {});
}
@override
bool shouldReload(covariant LocalizationsDelegate old) {
return false;
}
}
言語の切り替えが行われた場合、loadが呼び出されるのでIntl.defaultLocaleを変更し何もしないFutureを返している。
本来LocalizationsDelegateはジェネリッククラスなので何かクラスを指定する必要があるかもしれないけど、とりあえず動作しているのでいいかな?
補足 ローカライゼーションインスタンスを用意する方法
MaterialLocalizationsもしくはCupertinoLocalizationsみたいなものを自前で用意するにはどうするのか。
クラス構成としては以下の様になると思う。
- ILocalizations
リソースを提供するベースとするインターフェースクラス。 - DefaultLocalizations
多言語対応が行えるILocalizationsの実装で、delegateメンバでMaterialAppに渡すためのLocalizationsDelegateを渡せるようにしている。 - GlobalLocalizations
US Englishの情報を固定値として取り出せるようにしているILocalizationsの実装。 - _ILocalizationsDelegat
MaterialAppに渡すLocalizationsDelegateの実装。
上記クラスを用意することで、ILocalizations.of(context)でILocalizationsのインスタンスが取得できるので、保持する多言語版のリソース情報を取得できる。
詳細の実装についてはMaterialLocalizations、CupertinoLocalizationsを参考にすると良いと思う。
それほど難しくないし。
コメント