inq
inq

Reputation: 303

how to use localized strings in flutter's main app

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?

Upvotes: 2

Views: 1215

Answers (3)

Mr.Gao
Mr.Gao

Reputation: 1

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

Upvotes: 0

madlick71
madlick71

Reputation: 2436

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;
}

Upvotes: 0

koral
koral

Reputation: 2533

As documentation suggests:

To provide a localized title instead, use onGenerateTitle

Upvotes: 2

Related Questions