Flutter & i18n in a nutshell
During my first steps in develop some Flutter apps I came across - as always - the requirement for adding internationalization. In Flutter it's a three steps way to go to have i18n in your widgets. First of all you have to create a class to present your strings to the widget, then you have to run a command on the command line to generate a file which contains the basis of the translation which you then can translate yourself and finally you need to run another command to have a class generate which basically resolve the right translation for the requested string ... and don't forget to add some dependencies to the pubspec.yaml :).
dependencies:
flutter:
sdk: flutter
flutter_localizations:
sdk: flutter
flutter_cupertino_localizations: ^1.0.1
intl: ^0.15.8
...
dev_dependencies:
flutter_test:
sdk: flutter
intl_translation: ^0.17.1
...
Here it is in a nutshell:
- Create your app localization class
import 'dart:ui';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'i18n/messages_all.dart';
class AppLocalizations {
static Future<AppLocalizations> load(Locale locale) {
final String name = locale.countryCode.isEmpty ? locale.languageCode : locale.toString();
final String localeName = Intl.canonicalizedLocale(name);
return initializeMessages(localeName).then((_) {
Intl.defaultLocale = localeName;
return AppLocalizations();
});
}
static AppLocalizations of(BuildContext context) {
return Localizations.of<AppLocalizations>(context, AppLocalizations);
}
String get title {
return Intl.message(
'Hello World',
name: 'title',
desc: 'Title for the Demo application',
);
}
}
class AppLocalizationsDelegate extends LocalizationsDelegate<AppLocalizations> {
const AppLocalizationsDelegate();
@override
bool isSupported(Locale locale) => ['en', 'de'].contains(locale.languageCode);
@override
Future<AppLocalizations> load(Locale locale) => AppLocalizations.load(locale);
@override
bool shouldReload(AppLocalizationsDelegate old) => false;
}
** Sample code taken from https://proandroiddev.com/flutter-localization-step-by-step-30f95d06018d
Change the MaterialApp creation
class MyApp extends StatefulWidget {
@override
State<MyApp> createState() => MyAppState();
}
class MyAppState extends State<MyApp> {
@override
Widget build(BuildContext context) {
return MaterialApp(
localizationsDelegates: [
const AppLocalizationsDelegate(),
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
],
supportedLocales: [
const Locale('en', ''),
const Locale('de', ''),
],
title: 'MyApp',
home: MyWidget()
);
}
}
class MyWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
// TODO: implement build
return Scaffold(
appBar: AppBar(
title: Text(AppLocalizations.of(context).title()),
),
body: Center(
child: Text('Hello World'),
),
);
}
}```
2. Run the command on the command line
flutter pub pub run intl_translation:extract_to_arb --output-dir=lib/i18n lib/localizations.dart
As you can see I've put my above localization class code to a file called localizations.dart and I want to have the generated stuff in the i18n dir.
3. Run the command the generates the the dart class to retrieve the translated elements
flutter pub pub run intl_translation:generate_from_arb --output-dir=lib/i18n --no-use-deferred-loading lib/localizations.dart lib/i18n/intl_*.arb
See the part with intl_*, which are files with names like intl_en.arb and intl_de.arb which contain the same content als the in step 2 generated file intl_messages.arb
That's it, now you're good to go and you can use these translations in your code like
Text(AppLocalizations.of(context).title)
Some usefule links:
https://proandroiddev.com/flutter-localization-step-by-step-30f95d06018d
https://flutter.dev/docs/development/accessibility-and-localization/internationalization