I have the following code where I want to make sure my status will be localized in app, so I wanted to parse current locale and get value in needed language, but what it basically do, is simply remembering first language (locale) value parsed in it and staying with it till I restart my app
enum BillStatus {
sent,
processed,
...
}
extension BillStatusExtension on BillStatus {
static Map<BillStatus, String> names = {
BillStatus.sent: S.current.sent,
BillStatus.processed: S.current.processed,
...
};
String? get name => names[this];
}
S.current
means AppLocalizationDelegate
provided with intl
package
CodePudding user response:
When you do:
extension BillStatusExtension on BillStatus { static Map<BillStatus, String> names = { BillStatus.sent: S.current.sent, BillStatus.processed: S.current.processed, ... }; String? get name => names[this]; }
You're creating a names
Map
that's lazily initialized with whatever the values are of S.current.sent
, S.current.processed
, etc. are at the time names
is first accessed. When the locale changes, that Map
will never be updated and still will be referencing the same String
objects.
You should do one of:
Look up
S.current.sent
,S.current.processed
, etc. dynamically. An easy way to do this would be to change yourMap
to storeFunction
s instead ofString
s:extension BillStatusExtension on BillStatus { static Map<BillStatus, String Function()> names = { BillStatus.sent: () => S.current.sent, BillStatus.processed: () => S.current.processed, ... }; String? get name => names[this]?.call(); }
Alternatively explicitly reinitialize the
Map
when the locale changes. This is more work and likely is overkill in this case, but it's a technique that you can use if recomputing values on every lookup is too expensive:extension BillStatusExtension on BillStatus { static Map<BillStatus, String> names = {}; static String _lastLocale = ''; static void _initializeNames() { names[BillStatus.sent] = S.current.sent; names[BillStatus.processed] = S.current.processed; ... } String? get name { if (locale != _lastLocale) { _initializeNames(); _lastLocale = locale; } return names[this]; } }
Instead of reinitializing your
Map
lazily, you also could register a callback to do it immediately when the locale changes. See Is it possible to listen for system language change in Flutter?
CodePudding user response:
Your code should look like this:
void main() {
final status = BillStatus.sent;
print(status.name); // Sent
}
enum BillStatus { sent }
class BillStatusHelper {
static const Map<BillStatus, String> names = {
BillStatus.sent: 'Sent',
};
}
extension BillStatusExtension on BillStatus {
String get name => BillStatusHelper.names[this] ?? 'Unknown';
}