I'm facing an issue where I'm trying to use multiple LocalizationsDelegates
in a MaterialApp
.
I'm using the Dart intl
tools to provide translations to my labels. When I have multiple LocalizationsDelegates
only the one that is specified the first gets the translated values. The labels of the next delegate, get the default value provided in the Intl.message()
function.
I've set up a minimal project as an example of this issue on GitHub.
In the MaterialApp
, I define a bunch of localizationsDelegates
, including two app specific ones: DogLocalizationsDelegate
and CatLocalizationsDelegate
.
MaterialApp(
// other properties
locale: Locale("en"),
localizationsDelegates: [
CatLocalizationsDelegate(),
DogLocalizationsDelegate(),
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
],
supportedLocales: [
const Locale('en'),
const Locale('nl'),
],
);
The delegates have the same boilerplate code, but provide different labels.
Here's how the DogLocalizations
and its DogLocalizationsDelegate
look like.
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'messages_all.dart';
class DogLocalizations {
static Future<DogLocalizations> load(Locale locale) {
final String name = locale.languageCode;
final String localeName = Intl.canonicalizedLocale(name);
return initializeMessages(localeName).then((_) {
Intl.defaultLocale = localeName;
return DogLocalizations();
});
}
static DogLocalizations of(BuildContext context) {
return Localizations.of<DogLocalizations>(context, DogLocalizations);
}
String get bark {
return Intl.message(
'<insert dog sound>',
name: 'bark',
);
}
}
class DogLocalizationsDelegate extends LocalizationsDelegate<DogLocalizations> {
const DogLocalizationsDelegate();
@override
bool isSupported(Locale locale) => ['en', 'nl'].contains(locale.languageCode);
@override
Future<DogLocalizations> load(Locale locale) => DogLocalizations.load(locale);
@override
bool shouldReload(DogLocalizationsDelegate old) => false;
}
The CatLocalizations
are the same, but with a meow
String getter. Full example in the GitHub project.
I'm using multiple extraction and generation commands instead of having multiple files in one command. This is because I'm actually having this problem with a library (with its own labels) and a consumer of that library (that also has its own labels).
flutter pub run intl_translation:extract_to_arb --output-dir=lib/cat_labels/gen lib/cat_labels/CatLabels.dart
flutter pub run intl_translation:extract_to_arb --output-dir=lib/dog_labels/gen lib/dog_labels/DogLabels.dart
Translate the generated intl_messages.arb
to have two language files
Generate the dart files from ARB
flutter pub run intl_translation:generate_from_arb --output-dir=lib/cat_labels lib/cat_labels/CatLabels.dart lib/cat_labels/gen/intl_*.arb
flutter pub run intl_translation:generate_from_arb --output-dir=lib/dog_labels lib/dog_labels/DogLabels.dart lib/dog_labels/gen/intl_*.arb
In this demo project, having the following order of delegates:
// main.dart (line 20)
DogLocalizationsDelegate(),
CatLocalizationsDelegate(),
will give the translation for the bark
label, but not for the meow
label.
When switching it:
// main.dart (line 20)
CatLocalizationsDelegate(),
DogLocalizationsDelegate(),
will give the translation for the meow
label, but not for the bark
label.
In case you're wondering why: I'm using labels in a library and in the consumer apps of that library. Important to know is that it's not (really) possible to specify both localization files in the same generator command because of this.
From what I learned, no, you can’t use multiple localizations delegates like this. That is because intl’s initializeMessages
can only be called once per locale.
So in your example, once your CatLocalizationsDelegate
runs initializeMessages
, the one for DogLocalizationsDelegate
has no effect. That’s why you are only seeing the translation Meow!
but not Dog’s, or whichever one gets to run it first.
For additional reading, check out https://phrase.com/blog/posts/how-to-internationalize-a-flutter-app/ and please share feedback at https://github.com/flutter/flutter/issues/41437.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With