Flutter (89): Common issues with internationalization

Time: Column:Mobile & Frontend views:314

This section primarily addresses common issues encountered in internationalization.

1 Incorrect Default Locale

In some Android and iOS devices purchased from non-mainland channels, the default locale may not be Simplified Chinese. This is a normal occurrence; however, to prevent discrepancies between the locale retrieved by the device and the actual region, all multilingual apps must provide a manual language selection option.

2 How to Internationalize the App Title

The MaterialApp has a title property used to specify the app's title. On Android systems, the app's title appears in the task manager, so it also needs to be internationalized. The issue arises because many internationalization configurations are set on MaterialApp, and we cannot retrieve localized resources using Localizations.of when constructing MaterialApp, as shown below:

MaterialApp(
  title: DemoLocalizations.of(context).title, // This won't work!
  localizationsDelegates: [
    // Localization delegates
    GlobalMaterialLocalizations.delegate,
    GlobalWidgetsLocalizations.delegate,
    DemoLocalizationsDelegate() // Set the delegate
  ],
);

When the above code runs, DemoLocalizations.of(context).title will throw an error because Localizations.of searches up the widget tree from the current context to find DemoLocalizations. However, after setting DemoLocalizationsDelegate in MaterialApp, DemoLocalizations is actually in the subtree of the current context, causing DemoLocalizations.of(context) to return null, resulting in an error.

How can we handle this situation? It's quite simple: we just need to set an onGenerateTitle callback:

MaterialApp(
  onGenerateTitle: (context) {
    // At this point, context is within the Localizations subtree
    return DemoLocalizations.of(context).title;
  },
  localizationsDelegates: [
    DemoLocalizationsDelegate(),
    ...
  ],
);

3 How to Specify the Same Locale for English-Speaking Countries

There are many English-speaking countries, such as the United States, the United Kingdom, and Australia. Although they all speak English, there are some differences. If our app only wants to provide one version of English (e.g., American English) for all English-speaking countries, we can achieve compatibility using the localeListResolutionCallback introduced earlier:

localeListResolutionCallback:
    (List<Locale> locales, Iterable<Locale> supportedLocales) {
  // Check if the current locale is from an English-speaking country; if so, return Locale('en', 'US')
}