Home > Software engineering >  Dart / flutter: localization not accessible completely
Dart / flutter: localization not accessible completely

Time:10-04

I'm adding localization support to a webpage I'm building using Flutter dart. I can see that the title is displayed correctly using S.current.name property, but when the build comes to the widgets, it fails with the following error:

Assertion failed: file:///C:/dev/Adri/lib/generated/l10n.dart:21:12
_current != null
"No instance of S was loaded. Try to initialize the S delegate before accessing S.current."

My main() and HomePage looks like this:

void main() {
  runApp(const HomeScreen());
}

class HomeScreen extends StatelessWidget {
  const HomeScreen({super.key});

  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider<LanguageChangeProvider>(
      create: (context) => LanguageChangeProvider(),
      child: Builder(
        builder: (context) => MaterialApp(
            debugShowCheckedModeBanner: false,
            locale: Provider.of<LanguageChangeProvider>(context, listen: true)
                .currentLocale,
            localizationsDelegates: const [
              S.delegate,
              GlobalMaterialLocalizations.delegate,
              GlobalWidgetsLocalizations.delegate,
              GlobalCupertinoLocalizations.delegate
            ],
            supportedLocales: S.delegate.supportedLocales,
            //title: S.current.name,
            home: MyHomePage(title: S.current.name,)),
      ),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});
  
  final String title;

  @override
  State<StatefulWidget> createState() => _MyHomePageState();
}

As you can see, the S.current.name can be successfully passed down as the title of the website:

enter image description here

But it seems that the rest of the HomeScreen is unable to access this S for some reason:

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          actions: [
            IconButton(
                tooltip: SELECT_LANG_HU,
                onPressed: () {
                  languageChangeProcess(context, LOCALE_HU);
                },
                icon: const Icon(Icons.language)),
            IconButton(
                tooltip: SELECT_LANG_EN,
                onPressed: () {
                  languageChangeProcess(context, LOCALE_EN);
                },
                icon: const Icon(Icons.change_circle))
          ],
          iconTheme: const IconThemeData(color: Colors.grey),
          title: Text(
            S.current.name,
            style: TextStyle(color: Colors.grey.shade600),
          ),
          flexibleSpace: Container(
            decoration: BoxDecoration(
                gradient: LinearGradient(colors: <Color>[
              Colors.teal.shade50,
              Colors.teal.shade100,
            ])),
          ),
        ),
        body: Row(
          children: [Expanded(flex: 1, child: Container())],
        ),
        drawer: Drawer(
          child: ListView(
            children: [
              DrawerHeader(
                  decoration: BoxDecoration(
                      gradient: LinearGradient(colors: <Color>[
                    Colors.teal.shade50,
                    Colors.teal.shade100
                  ])),
                  padding:
                      const EdgeInsets.only(left: 2.0, right: 2.0, top: 4.0),
                  child: const ContactCard()),
              MenuElement(Icons.person, S.current.introduction, () => {}),
              MenuElement(Icons.school, S.current.education, () => {}),
              MenuElement(
                  Icons.workspace_premium, S.current.publications, () => {}),
              MenuElement(Icons.work, S.current.workExperience, () => {}),
            ],
          ),
        ));
  }

Am I missing something obvious?

In the pubsec.yaml I added this dependency:

  flutter_localizations:
    sdk: flutter
  provider: ^5.0.0

CodePudding user response:

  • Did you add the code below to pubspec.yaml?
flutter:
  generate: true

If you haven't added it, you can check it out here. fluttter.dev

CodePudding user response:

By the way, you have to call your string from the localization file like this: For example: S.of(context)!.title

Recommendation: Instead of calling

localizationsDelegates: const [
              S.delegate,
              GlobalMaterialLocalizations.delegate,
              GlobalWidgetsLocalizations.delegate,
              GlobalCupertinoLocalizations.delegate
            ],

You can call this one :

 localizationsDelegates: S.localizationsDelegates,

This is the short version of calling localizationsDelegates

CodePudding user response:

I seem to have found a solution for my problem, if I initialize the localization inside main(), it will work (except for the title, but that's the least of issues).

void main() {
  runApp(ChangeNotifierProvider<LanguageChangeProvider>(
    create: (context) => LanguageChangeProvider(),
    child: Builder(
        builder: (context) => MaterialApp(
              localizationsDelegates: const [
                S.delegate,
                GlobalMaterialLocalizations.delegate,
                GlobalWidgetsLocalizations.delegate,
                GlobalCupertinoLocalizations.delegate
              ],
              debugShowCheckedModeBanner: false,
              locale: Provider.of<LanguageChangeProvider>(context, listen: true)
                  .currentLocale,
              supportedLocales: S.delegate.supportedLocales,
              home: HomeScreen(),
            )),
  ));
}

class HomeScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MyHomePage();
  }
}

Swapping between localizations works now like a charm.

  • Related