Flutterで多言語対応していく(検討中)
Flutterの多言語対応については公式ドキュメントが詳しい。
のだけれども、どうにも AppLocalizations
を使いたくないという気持ちが出てしまう。
また自分が普段使っているマイクロサービス化された開発だと、統合するアプリケーションでは利用できても、ライブラリ化された箇所では利用できなかったりする。
半ば実験中なのだけれども、Riverpodを使って多言語対応させる方法を書いてみる。
文字列を入力するファイルを作る。
ベースを localization.dart
とし、日本語のデータを追加するファイルを localization_ja.dart
とでもすることにする。
localization.dart
part 'localization_ja.dart';
class Localization {
const Localization({
required this.appName,
});
final String appName;
}
localizaziton_ja.dart
part of 'localization.dart';
const _ja = Localization(
appName: 'アプリケーション',
);
あとは、これを Provider
を使って配布できるようにするだけ。
import 'package:hooks_riverpod/hooks_riverpod.dart';
final localizationProvider = Provider(
(ref) => _ja,
);
同一ファイルなので、 _
をつけてprivateにすることができる。
この対応をすることで、あとはProviderで Locale
を配布することができれば、自動的に表示される文字列が切り替わるようになる。
localization_en.dart
として英語の文字列を管理するファイルを追加する。
localization_en.dart
part of 'localization.dart';
const _en = Localization(
appName: 'Application',
);
あとは、次のProviderが動くようにすれば良い。
final localizationProvider = Provider(
(ref) {
final locale = ref.watch(localeProvider);
if (locale.languageCode == 'ja') {
return _ja;
}
return _en;
},
);
Riverpodで Locale
を配布する方法はいくつかあるようなので、それを参照すれば良い。
今回の場合、アプリケーションに与える文字列をいじってしまっているので、ちょっとだけ工夫が必要になってくる。
今試しているのは下記のような実装。
まず、 Locale
を StateProvider
で配布しておく。
import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
const kDefaultLocale = Locale('en');
final localeProvider = StateProvider(
(ref) => kDefaultLocale,
);
続いて MaterialApp
に次の実装を追加しておく。
MaterialApp(
localeResolutionCallback: (locale, supportedLocales) {
final languageCodes = supportedLocales.map((e) => e.languageCode);
if (locale != null) {
if (languageCodes.contains(locale.languageCode)) {
WidgetsBinding.instance.addPostFrameCallback((_) {
ref.read(localeProvider.notifier).state = locale;
});
return locale;
}
}
WidgetsBinding.instance.addPostFrameCallback((_) {
ref.read(localeProvider.notifier).state = kDefaultLocale;
});
return kDefaultLocale;
},
~~~
);
これで、先ほど作った localizationProvider
の中身が切り替わるようになる。
クラッシュの危険とか、パフォーマンスの問題とかあるかもとは思っているで、色々と調査をしていきたい。