Reputation: 91
I successfully created my newly supported language which is 'rw' (Rwandan language), and you can change the state of language but every time I restart the app while in my language('rw') state, I get the following error, does anyone know how to resolve this issue?
The following ArgumentError was thrown building:
Invalid argument(s): Invalid locale "en_US"
When the exception was thrown, this was the stack
#0 _throwLocaleError
package:intl/src/intl_helpers.dart:177
#1 verifiedLocale
package:intl/src/intl_helpers.dart:171
#2 verifiedLocale
package:intl/src/intl_helpers.dart:156
#3 new DateFormat
package:intl/…/intl/date_format.dart:266
#4 new DateFormat.yMEd
package:intl/…/intl/date_format.dart:478
Here is my rw_intl.dart file
import 'dart:async';
import 'package:intl/intl.dart' as intl;
import 'package:intl/date_symbols.dart' as intl;
import 'package:intl/date_symbol_data_custom.dart' as date_symbol_data_custom;
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
/// A custom set of date patterns for the `rw` locale.
///
/// These are not accurate and are just a clone of the date patterns for the
/// `no` locale to demonstrate how one would write and use custom date patterns.
const rwLocaleDatePatterns = {
'd': 'd.',
'E': 'ccc',
'EEEE': 'cccc',
'LLL': 'LLL',
'LLLL': 'LLLL',
'M': 'L.',
'Md': 'd.M.',
'MEd': 'EEE d.M.',
'MMM': 'LLL',
'MMMd': 'd. MMM',
'MMMEd': 'EEE d. MMM',
'MMMM': 'LLLL',
'MMMMd': 'd. MMMM',
'MMMMEEEEd': 'EEEE d. MMMM',
'QQQ': 'QQQ',
'QQQQ': 'QQQQ',
'y': 'y',
'yM': 'M.y',
'yMd': 'd.M.y',
'yMEd': 'EEE d.MM.y',
'yMMM': 'MMM y',
'yMMMd': 'd. MMM y',
'yMMMEd': 'EEE d. MMM y',
'yMMMM': 'MMMM y',
'yMMMMd': 'd. MMMM y',
'yMMMMEEEEd': 'EEEE d. MMMM y',
'yQQQ': 'QQQ y',
'yQQQQ': 'QQQQ y',
'H': 'HH',
'Hm': 'HH:mm',
'Hms': 'HH:mm:ss',
'j': 'HH',
'jm': 'HH:mm',
'jms': 'HH:mm:ss',
'jmv': 'HH:mm v',
'jmz': 'HH:mm z',
'jz': 'HH z',
'm': 'm',
'ms': 'mm:ss',
's': 's',
'v': 'v',
'z': 'z',
'zzzz': 'zzzz',
'ZZZZ': 'ZZZZ',
};
/// A custom set of date symbols for the `rw` locale.
///
/// These are not accurate and are just a clone of the date symbols for the
/// `no` locale to demonstrate how one would write and use custom date symbols.
const rwDateSymbols = {
'NAME': 'rw',
'ERAS': <dynamic>[
'm.Kr.',
'n.Kr.',
],
'ERANAMES': <dynamic>[
'mbere ya Kristu',
'nyuma ya Kristu',
],
'NARROWMONTHS': <dynamic>[
'M',
'G',
'W',
'M',
'G',
'K',
'N',
'K',
'N',
'U',
'U',
'U',
],
'STANDALONENARROWMONTHS': <dynamic>[
'M',
'G',
'W',
'M',
'G',
'K',
'N',
'K',
'N',
'U',
'U',
'U',
],
'MONTHS': <dynamic>[
'Mutarama',
'Gashyantare',
'Werurwe',
'Mata',
'Gicurasi',
'Kamena',
'Nyakanga',
'Kanama',
'Nzeli',
'Ukwakira',
'Ugushyingo',
'Ukuboza',
],
'STANDALONEMONTHS': <dynamic>[
'Mutarama',
'Gashyantare',
'Werurwe',
'Mata',
'Gicurasi',
'Kamena',
'Nyakanga',
'Kanama',
'Nzeli',
'Ukwakira',
'Ugushyingo',
'Ukuboza',
],
'SHORTMONTHS': <dynamic>[
'Mut.',
'Gas.',
'Wer.',
'Mat.',
'Gic.',
'Kam.',
'Nya.',
'Kan.',
'Nze.',
'Ukw.',
'Ugu.',
'Uku.',
],
'STANDALONESHORTMONTHS': <dynamic>[
'Mut.',
'Gas.',
'Wer.',
'Mat.',
'Gic.',
'Kam.',
'Nya.',
'Kan.',
'Nze.',
'Ukw.',
'Ugu.',
'Uku.',
],
'WEEKDAYS': <dynamic>[
'ku cyumweru',
'ku wa mbere',
'ku wa kabiri',
'ku wa gatatu',
'ku wa kane',
'ku wa gatanu',
'ku wa gatandatu',
],
'STANDALONEWEEKDAYS': <dynamic>[
'ku cyumweru',
'ku wa mbere',
'ku wa kabiri',
'ku wa gatatu',
'ku wa kane',
'ku wa gatanu',
'ku wa gatandatu',
],
'SHORTWEEKDAYS': <dynamic>[
'cyumwer.',
'mbere.',
'kabiri.',
'gatatu.',
'kane.',
'gatanu.',
'gatandat.',
],
'STANDALONESHORTWEEKDAYS': <dynamic>[
'cyumwer.',
'mbere.',
'kabiri.',
'gatatu.',
'kane.',
'gatanu.',
'gatandat.',
],
'NARROWWEEKDAYS': <dynamic>[
'C',
'M',
'K',
'G',
'K',
'G',
'G',
],
'STANDALONENARROWWEEKDAYS': <dynamic>[
'C',
'M',
'K',
'G',
'K',
'G',
'G',
],
'SHORTQUARTERS': <dynamic>[
'K1',
'K2',
'K3',
'K4',
],
'QUARTERS': <dynamic>[
'kimwe cya kane',
'bibiri bya kane',
'bitatu bya kane',
'bine bya kane',
],
'AMPMS': <dynamic>[
'za mu gitondo',
'z\' umugoroba ',
],
'DATEFORMATS': <dynamic>[
'EEEE d. MMMM y',
'd. MMMM y',
'd. MMM y',
'dd.MM.y',
],
'TIMEFORMATS': <dynamic>[
'HH:mm:ss zzzz',
'HH:mm:ss z',
'HH:mm:ss',
'HH:mm',
],
'AVAILABLEFORMATS': null,
'FIRSTDAYOFWEEK': 0,
'WEEKENDRANGE': <dynamic>[
5,
6,
],
'FIRSTWEEKCUTOFFDAY': 3,
'DATETIMEFORMATS': <dynamic>[
'{1} {0}',
'{1} \'kl\'. {0}',
'{1}, {0}',
'{1}, {0}',
],
};
class _RwMaterialLocalizationsDelegate
extends LocalizationsDelegate<MaterialLocalizations> {
const _RwMaterialLocalizationsDelegate();
@override
bool isSupported(Locale locale) => locale.languageCode == 'rw';
@override
Future<MaterialLocalizations> load(Locale locale) async {
final String localeName = intl.Intl.canonicalizedLocale(locale.toString());
// The locale (in this case `rw`) needs to be initialized into the custom
// date symbols and patterns setup that Flutter uses.
date_symbol_data_custom.initializeDateFormattingCustom(
locale: localeName,
patterns: rwLocaleDatePatterns,
symbols: intl.DateSymbols.deserializeFromMap(rwDateSymbols),
);
return SynchronousFuture<MaterialLocalizations>(
RwMaterialLocalizations(
localeName: localeName,
// The `intl` library's NumberFormat class is generated from CLDR data
// (see https://github.com/dart-lang/intl/blob/master/lib/number_symbols_data.dart).
// Unfortunately, there is no way to use a locale that isn't defined in
// this map and the only way to work around this is to use a listed
// locale's NumberFormat symbols. So, here we use the number formats
// for 'en_US' instead.
decimalFormat: intl.NumberFormat('#,##0.###', 'en_US'),
twoDigitZeroPaddedFormat: intl.NumberFormat('00', 'en_US'),
// DateFormat here will use the symbols and patterns provided in the
// `date_symbol_data_custom.initializeDateFormattingCustom` call above.
// However, an alternative is to simply use a supported locale's
// DateFormat symbols, similar to NumberFormat above.
fullYearFormat: intl.DateFormat('y', localeName),
compactDateFormat: intl.DateFormat('yMd', localeName),
shortDateFormat: intl.DateFormat('yMMMd', localeName),
mediumDateFormat: intl.DateFormat('EEE, MMM d', localeName),
longDateFormat: intl.DateFormat('EEEE, MMMM d, y', localeName),
yearMonthFormat: intl.DateFormat('MMMM y', localeName),
shortMonthDayFormat: intl.DateFormat('MMM d', localeName),
),
);
}
@override
bool shouldReload(_RwMaterialLocalizationsDelegate old) => false;
}
/// A custom set of localizations for the 'rw' locale. In this example, only
/// the value for openAppDrawerTooltip was modified to use a custom message as
/// an example. Everything else uses the American English (en_US) messages
/// and formatting.
class RwMaterialLocalizations extends GlobalMaterialLocalizations {
const RwMaterialLocalizations({
String localeName = 'rw',
@required intl.DateFormat fullYearFormat,
@required intl.DateFormat compactDateFormat,
@required intl.DateFormat shortDateFormat,
@required intl.DateFormat mediumDateFormat,
@required intl.DateFormat longDateFormat,
@required intl.DateFormat yearMonthFormat,
@required intl.DateFormat shortMonthDayFormat,
@required intl.NumberFormat decimalFormat,
@required intl.NumberFormat twoDigitZeroPaddedFormat,
}) : super(
localeName: localeName,
fullYearFormat: fullYearFormat,
compactDateFormat: compactDateFormat,
shortDateFormat: shortDateFormat,
mediumDateFormat: mediumDateFormat,
longDateFormat: longDateFormat,
yearMonthFormat: yearMonthFormat,
shortMonthDayFormat: shortMonthDayFormat,
decimalFormat: decimalFormat,
twoDigitZeroPaddedFormat: twoDigitZeroPaddedFormat,
);
@override
String get moreButtonTooltip => r'Ibindi';
@override
String get aboutListTileTitleRaw => r'Ibijyanye $applicationName';
@override
String get alertDialogLabel => r'Imenyesha';
@override
String get anteMeridiemAbbreviation => r'AM';
@override
String get backButtonTooltip => r'Inyuma';
@override
String get cancelButtonLabel => r'HAGARIKA';
@override
String get closeButtonLabel => r'FUNGA';
@override
String get closeButtonTooltip => r'Funga';
@override
String get collapsedIconTapHint => r'Agura';
@override
String get continueButtonLabel => r'KOMEZA';
@override
String get copyButtonLabel => r'KOPIYA';
@override
String get cutButtonLabel => r'KATINGA';
@override
String get deleteButtonTooltip => r'Siba';
@override
String get dialogLabel => r'Ikiganiro';
@override
String get drawerLabel => r'Ibikubiyemo';
@override
String get expandedIconTapHint => r'Gabanya';
@override
String get hideAccountsLabel => r'Hishya konte';
@override
String get licensesPageTitle => r'Licenses';
@override
String get modalBarrierDismissLabel => r'Dismiss';
@override
String get nextMonthTooltip => r'Ukwezi gutaha';
@override
String get nextPageTooltip => r'Paji ikurikira';
@override
String get okButtonLabel => r'KOMEZA';
@override
// A custom drawer tooltip message.
String get openAppDrawerTooltip => r'Custom Navigation Menu Tooltip';
@override
String get pageRowsInfoTitleRaw => r'$firstRow–$lastRow of $rowCount';
@override
String get pageRowsInfoTitleApproximateRaw =>
r'$firstRow–$lastRow of about $rowCount';
@override
String get pasteButtonLabel => r'PASTE';
@override
String get popupMenuLabel => r'Popup menu';
@override
String get postMeridiemAbbreviation => r'PM';
@override
String get previousMonthTooltip => r'Ukwezi gushize';
@override
String get previousPageTooltip => r'Paji ibanza';
@override
String get refreshIndicatorSemanticLabel => r'Refresh';
@override
String get remainingTextFieldCharacterCountFew => null;
@override
String get remainingTextFieldCharacterCountMany => null;
@override
String get remainingTextFieldCharacterCountOne => r'inyuguti imwe isigaye';
@override
String get remainingTextFieldCharacterCountOther =>
r'inyuguti $remainingCount zisigaye';
@override
String get remainingTextFieldCharacterCountTwo => null;
@override
String get remainingTextFieldCharacterCountZero => r'Nta nyuguti isigaye';
@override
String get reorderItemDown => r'Manuka';
@override
String get reorderItemLeft => r'Jya ibumoso';
@override
String get reorderItemRight => r'Jya iburyo';
@override
String get reorderItemToEnd => r'Manuka ahahera';
@override
String get reorderItemToStart => r'Zamuka ahabanza';
@override
String get reorderItemUp => r'Zamuka';
@override
String get rowsPerPageTitle => r'Rows per page:';
@override
ScriptCategory get scriptCategory => ScriptCategory.englishLike;
@override
String get searchFieldLabel => r'Ishakiro';
@override
String get selectAllButtonLabel => r'HITAMO BYOSE';
@override
String get selectedRowCountTitleFew => null;
@override
String get selectedRowCountTitleMany => null;
@override
String get selectedRowCountTitleOne => r'1 item selected';
@override
String get selectedRowCountTitleOther => r'$selectedRowCount items selected';
@override
String get selectedRowCountTitleTwo => null;
@override
String get selectedRowCountTitleZero => r'No items selected';
@override
String get showAccountsLabel => r'Garagaza konte';
@override
String get showMenuTooltip => r'Garagaza Ibikubiyemo';
@override
String get signedInLabel => r'Winjiye';
@override
String get tabLabelRaw => r'Tab $tabIndex of $tabCount';
@override
TimeOfDayFormat get timeOfDayFormatRaw => TimeOfDayFormat.h_colon_mm_space_a;
@override
String get timePickerHourModeAnnouncement => r'Hitamo amasaha';
@override
String get timePickerMinuteModeAnnouncement => r'Hitamo iminota';
@override
String get viewLicensesButtonLabel => r'VIEW LICENSES';
@override
List<String> get narrowWeekdays =>
const <String>['C', 'M', 'K', 'G', 'K', 'G', 'G'];
@override
int get firstDayOfWeekIndex => 0;
static const LocalizationsDelegate<MaterialLocalizations> delegate =
_RwMaterialLocalizationsDelegate();
@override
String get calendarModeButtonLabel => r'Jya kuri kalendari';
@override
String get dateHelpText => r'mm/dd/yyyy';
@override
String get dateInputLabel => r'Injiza itariki';
@override
String get dateOutOfRangeLabel => r'Out of range.';
@override
String get datePickerHelpText => r'HITAMO ITARIKI';
@override
String get dateRangeEndDateSemanticLabelRaw => r'Itariki ihera $fullDate';
@override
String get dateRangeEndLabel => r'Itariki ihera';
@override
String get dateRangePickerHelpText => 'HITAMO INTERA';
@override
String get dateRangeStartDateSemanticLabelRaw => 'Itariki ibanza \$fullDate';
@override
String get dateRangeStartLabel => 'Itariki ibanza';
@override
String get dateSeparator => '/';
@override
String get dialModeButtonLabel => 'Switch to dial picker mode';
@override
String get inputDateModeButtonLabel => 'Switch to input';
@override
String get inputTimeModeButtonLabel => 'Switch to text input mode';
@override
String get invalidDateFormatLabel => 'Invalid format.';
@override
String get invalidDateRangeLabel => 'Invalid range.';
@override
String get invalidTimeLabel => 'Enter a valid time';
@override
String get licensesPackageDetailTextOther => '\$licenseCount licenses';
@override
String get saveButtonLabel => 'BIKA';
@override
String get selectYearSemanticsLabel => 'Hitamo umwaka';
@override
String get timePickerDialHelpText => 'HITAMO IGIHE';
@override
String get timePickerHourLabel => 'Isaha';
@override
String get timePickerInputHelpText => 'INJIZA GIHE';
@override
String get timePickerMinuteLabel => 'Umunota';
@override
String get unspecifiedDate => 'Itariki';
@override
String get unspecifiedDateRange => 'Date Range';
}
Here is my main.dart file
`locale: _locale,
supportedLocales: [
Locale('en'),
Locale('rw'),
],
localizationsDelegates: [
DemoLocalization.delegate,
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
RwMaterialLocalizations.delegate,
],
localeResolutionCallback: (deviceLocale, supportedLocales) {
for (var locale in supportedLocales) {
if (locale.languageCode == deviceLocale.languageCode) {
return deviceLocale;
}
}
return supportedLocales.first;
},`
Upvotes: 5
Views: 4275
Reputation: 788
You need to add it to intl
cache as well:
...
date_symbol_data_custom.initializeDateFormattingCustom(
locale: localeName,
patterns: rwLocaleDatePatterns,
symbols: intl.DateSymbols.deserializeFromMap(rwDateSymbols),
);
date_symbol_data_custom.initializeDateFormattingCustom(
locale: 'en_US',
patterns: dateTimePatternMap()['en_US'],
symbols: dateTimeSymbolMap()['en_US'],
);
...
Upvotes: 0
Reputation: 341
The issue is that you have set supported locales to :
supportedLocales: [
Locale('en'),
Locale('rw'),
],
Replace Locale('en') with Locale('en_US') as the error is suggesting . The reason you are getting the error is because your device locale is en_US and not en. Best approach would be to centralise your supported locales. If you have the intl plugin in your code editor (VS code or Android Studio) then you should have this generated folder (lib/generated/l10n.dart). In this file you will find a class called AppLocalizationDelegate in this class you will find a list of supportedLocales. In your main.dart call this list
import 'package:your_package_name_here/generated/l10n.dart';
supportedLocales: AppLocalizationDelegate().supportedLocales,
Upvotes: 0