how to use localized strings in flutter's main app

781 Views Asked by At

I am new to Flutter and I am building a localized app using the flutter-intl plugin. I've declared a "Title" string in the .arb file for my locales. My program is trying to use this string as follows:

  Widget build(BuildContext context) {
    return MaterialApp(
      localizationsDelegates: [
        S.delegate,
        GlobalMaterialLocalizations.delegate,
        GlobalWidgetsLocalizations.delegate,
        GlobalCupertinoLocalizations.delegate,
      ],
      supportedLocales: S.delegate.supportedLocales,
      title: S.current.Title,

I've tried using S.current.Title and S.of(context).Title, and in both cases when the program starts I get the following error message: enter image description here

When I change the title property to title: 'my title', the app performs hot-reload and the error screen disappears. When I change the title back to title: S.current.Title the localized title is displayed with no error.

This behavior has been consistently confirmed with Android-studio and VS-Code with web and Android targets.

I guess it has to do with Flutter's initialization sequence. What is the proper way to use localized strings as properties in the MaterialApp?

3

There are 3 best solutions below

0
On BEST ANSWER

As documentation suggests:

To provide a localized title instead, use onGenerateTitle

1
On
MaterialApp(
  // title: 'your title',
  onGenerateTitle: (context) => 
      S.maybeOf(context) != null ? S.current.title : 'your default title',
);
0
On

Try this.

main.dart:

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart';

import 'config/languages/localizations.dart';
import 'config/languages/localizations_delegate.dart';
import 'homepage.dart';

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

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

  @override
  Widget build(BuildContext context) => MaterialApp(
        debugShowCheckedModeBanner: false,
        localizationsDelegates: const [
          MyLocalizationsDelegate(),
          GlobalMaterialLocalizations.delegate,
          GlobalWidgetsLocalizations.delegate,
          GlobalCupertinoLocalizations.delegate,
        ],
        supportedLocales: const [
          Locale('en', ''),
          Locale('de', ''),
        ],
        onGenerateTitle: (context) => MyLocalizations.of(context)?.title ?? '',
        theme: ThemeData(primarySwatch: Colors.blue),
        home: const MyHomePage(),
      );
}

localizations.dart:

import 'package:flutter/material.dart';

class MyLocalizations {
  MyLocalizations(this.locale);

  final Locale locale;

  static MyLocalizations? of(BuildContext context) =>
      Localizations.of<MyLocalizations>(context, MyLocalizations);

  static languages() => _localizedValues.keys.toList();

  String get title => _localizedValues[locale.languageCode]!['title']!;

  static const _localizedValues = <String, Map<String, String>>{
    'en': {
      'title': 'Hello World',
    },
    'de': {
      'title': 'Hallo Welt',
    },
  };
}

localizations_delegate.dart:

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';

import 'localizations.dart';

class MyLocalizationsDelegate extends LocalizationsDelegate<MyLocalizations> {
  const MyLocalizationsDelegate();

  @override
  bool isSupported(Locale locale) =>
      MyLocalizations.languages().contains(locale.languageCode);

  @override
  Future<MyLocalizations> load(Locale locale) =>
      SynchronousFuture<MyLocalizations>(MyLocalizations(locale));

  @override
  bool shouldReload(MyLocalizationsDelegate old) => false;
}