Flutter app crashes building the AppBar with multi language using i18n Jetbrains plugin's boilerplate

2,082

The problem is not about the boilerplate code or configuration.

The meaning of the error is that there is no support for the language "it_" for the "default system strings". (In particular it crashes due to some default tooltip of the AppBar -> that's why it is crashing if an AppBar is displayed).

As reported in this Q&A you can solve the issue by implementing your own LocalizationsDelegate.

Full fix

class MaterialLocalizationItDelegate extends LocalizationsDelegate<MaterialLocalizations> {
  /// Here list supported country and language codes
  @override
  bool isSupported(Locale locale) => locale.languageCode == "it";
  /// Here create an instance of your [MaterialLocalizations] subclass
  @override
  Future<MaterialLocalizations> load(Locale locale) async => MaterialLocalizationIt();
  @override
  bool shouldReload(_) => false;
}

class MaterialLocalizationIt extends MaterialLocalizations {
  // alt-enter on intellij and implement many overrides (somthing like 57)
}

And then append your delegate to the list of delegates:

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      localizationsDelegates: [S.delegate, MaterialLocalizationItDelegate()],  // <- append here
      supportedLocales: S.delegate.supportedLocales,
      home: MyHomePage(),
    );
  }
}

Quick fix

An hasty way to check if this will work for you before implementing the 57 overrides.
Copy exactly this code:

class FallbackLocalizationDelegate extends LocalizationsDelegate<MaterialLocalizations> {
  @override
  bool isSupported(Locale locale) => true;
  @override
  Future<MaterialLocalizations> load(Locale locale) async => DefaultMaterialLocalizations();
  @override
  bool shouldReload(_) => false;
}

The above class claim to support all locales (isSupported(Locale locale) => true) and simply returns the default en_US locale.
Finally add this to your list of delegates.

localizationsDelegates: [S.delegate, FallbackLocalizationDelegate()],  // <- append here

This quick fix will set all the default system strings to English, but your "custom" localization should work.

Share:
2,082
Pado
Author by

Pado

Updated on December 14, 2022

Comments

  • Pado
    Pado over 1 year

    I'm using Flutter i18n plugin for Android Studio following the official documentation.

    I added the few configuration line needed to a minimal app that displays a String:

    void main() => runApp(MyApp());
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          localizationsDelegates: [S.delegate],
          supportedLocales: S.delegate.supportedLocales,
          home: MyHomePage(),
        );
      }
    }
    
    class MyHomePage extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return Scaffold(
    //      appBar: AppBar(
    //        title: Text("Hard-coded English string"),
    //      ),
          body: Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                Text(S.of(context).string_that_should_be_internationalized),
              ],
            ),
          ),
        );
      }
    }
    

    This is working (the string is actually translated to my phone system language). But a warning is thrown at every call to build:

    Warning: This application's locale, it_, is not supported by all of its
    localization delegates.
    > A MaterialLocalizations delegate that supports the it_ locale was not found.
    

    Despite S.delegate.supportedLocales being [en_, it_] and all arb file being correctly configured.

    I can make the Scaffold body arbitrarily complicated and the behavior remains the same (i18n works with warning). But if I add a simple AppBar (even if the widged does not require translation) to the Scaffold the whole application crashes. (E.g. uncommenting in the snippet above)

    Abstract of the error:

    I/flutter (11411): No MaterialLocalizations found.
    I/flutter (11411): AppBar widgets require MaterialLocalizations to be provided by a Localizations widget ancestor.
    I/flutter (11411): Localizations are used to generate many different messages, labels,and abbreviations which are used
    I/flutter (11411): by the material library.
    I/flutter (11411): To introduce a MaterialLocalizations, either use a  MaterialApp at the root of your application to
    I/flutter (11411): include them automatically, or add a Localization widget with a MaterialLocalizations delegate.
    I/flutter (11411): The specific widget that could not find a MaterialLocalizations ancestor was:
    I/flutter (11411):   AppBar
    

    The framework is complaining about my AppBar not having a Localizations widget ancestor. But it actually have because it's inside a MaterialApp. No clue on how to solve this mystery.

    Full log

    EDIT
    Another weird thing i just discovered: running the same exact app in --release mode gets rid of all the errors and warnings; everything is correctly translated including the AppBar.
    Still wondering why it crashes in --debug mode.

  • Javeed Ishaq
    Javeed Ishaq over 2 years
    thanks a lot Pado, you saved my day thanks thanks