我有一个使用
EasyLocalization
包进行本地化的包,我想将此包的 localizationsDelegate
添加到我的主项目中。
我知道我可以使用
flutter_intl
包将类似的内容添加到 pubspec.yaml
:
flutter_intl:
main_locale: en
enabled: true
class_name: MyPackageLocalization
并将
MyPackageLocalization.delegate
添加到 localizationsDelegates
内的我的 MaterialApp
:
...
MaterialApp(
localizationsDelegates: [
...context.localizationDelegates,
MyPackageLocalization.delegate,
],
supportedLocales: context.supportedLocales,
...
但是,我该如何使用
EasyLocalization
包来做到这一点?
我找到了解决办法,首先我们需要定义一个
MultiTranslationAssetLoader
班级:
class MultiTranslationAssetLoader extends AssetLoader {
const MultiTranslationAssetLoader(this.loaders);
final List<dynamic> loaders;
@override
Future<Map<String, dynamic>> load(String path, Locale locale) async {
final result = <String, dynamic>{};
final loaderFutures = <Future<Map<String, dynamic>?>>[];
for (final loader in loaders) {
loaderFutures.add(loader.load(path, locale));
}
(await Future.wait(loaderFutures))
.whereNotNull()
.forEach(result.addAllRecursive);
return result;
}
}
extension _MapExtension<K> on Map<K, dynamic> {
void addAllRecursive(Map<K, dynamic> other) {
for (final entry in other.entries) {
final oldValue = this[entry.key];
final newValue = entry.value;
if (oldValue is Map<K, dynamic> && newValue is Map<K, dynamic>) {
oldValue.addAllRecursive(newValue);
continue;
}
this[entry.key] = newValue;
}
}
}
然后我们可以如下使用:
EasyLocalization(
supportedLocales: const <Locale>[
Locale('en'),
],
fallbackLocale: const Locale('en'),
assetLoader: const MultiTranslationAssetLoader(
[
TranslationsLoader(),
TranslationsLoader(packageName: 'package_example'),
],
),
path: 'lib/l10n/translations',
child: const MainApp(),
),
);
这是
TranslationsLoader
的示例实现:
class TranslationsLoader extends AssetLoader {
const TranslationsLoader({this.packageName});
final String? packageName;
@override
Future<Map<String, dynamic>?> load(String path, Locale locale) =>
_getMapLocales(locale);
Future<Map<String, dynamic>> _getMapLocales(Locale locale) async {
String getPath({Locale locale = const Locale('en')}) =>
'${packageName != null ? 'packages/$packageName/' : ''}lib/l10n/translations/$locale.json';
try {
return jsonDecode(await rootBundle.loadString(getPath(locale: locale)));
} catch (e) {
return jsonDecode(await rootBundle.loadString(getPath()));
}
}
}
这篇文章帮助我解决了这个问题: