Flutter Localization

Kothai Rajagopalan
4 min readDec 11, 2019

--

Flutter provides English US as its default language. However it also provides support to various other languages, approximately about 73 languages as well. To do so, the application must include ‘flutter_localizations’ package and few extra MaterialApp properties. If the app is to work smoothly on iOS, then an additional ‘flutter_cupertino_localizations’ package is to be added. Flutter localization is commonly referred to us as l10n. l10n is just a shorthand for Flutter localization, which stands for number of letters between l and n in localization.

Flutter Localization allows to adapt, the application to more markets by, translating the string into different languages, adding different currencies units, adding different measuring units, adding different dates, address, name and phone numbers etc., It helps your application to fit the needs of the users. It also allows the legal ramifications.

Localization is a widget in Flutter just like any other. It is implemented as inherited widget model, that allows access to localization from any place in the application once we implement it. Flutter SDK comes with different library choices, and the common among them are intl and flutter_localization, which uses mostly either .arb, JSON, code generation or simple Maps. The Locale class and the localization widgets are not just add-ons, but are directly added into SDK. It allows us to change the text direction and also the orientation of the widgets based on locale. We can also dynamically change the localization on resume and reload.

Let’s build a simple example app, that supports Japanese and English languages using Flutter localization and by using .arb and code generation. Create a new Flutter Project in Android Studio or VS Code.

Adding the new dependencies: The ‘flutter_localizations’ package is added under the dependencies and the ‘intl_translation’ package is added to the dev_dependencies of pubspec.yaml file. The ‘intl_translation’ package provides the tools to generate the dart code with the messages from .arb file.

dependencies:
flutter:
sdk: flutter
flutter_localizations:
sdk: flutter
dev_dependencies:
intl_translation: ^0.17.1
flutter_test:
sdk: flutter

Creation of AppLocalizations class: Create a localizations.dart file under the lib folder and create a class named AppLocalizations . This class has four main sections namely,

the load function — that loads the string parameter from the selected locale,

the of function — is a helper and is required for the InheritedWidget to ease the access to any string parameter from any part of the app code ,

the get function — will be the list of required strings that needs to be translated in our app and

the initializeMessages — which contains the method that loads the translated messages and it will be generated by the intl tool, for which we need to import ‘l10n/messages_all.dart’ in our file.

The AppLocalizations class has another class namely, AppLocalizationsDelegate, which contains the real localization class for our app. The AppLocalizations class combines the resources and the AppLocalizationsDelegate, to provide the necessary resource to our app. It consists of three main sections namely,

the load method — which usually returns an object that contains a collection of related string resources,

the isSupported method — which returns true, when the app has a support for requested locale, and

the shouldReload method — if this method is true, it usually rebuilds the entire app widgets after the load of resources.

class AppLocalizations {
static Future<AppLocalizations> load(Locale locale) {
final String name =
locale.countryCode.isEmpty ? locale.languageCode : locale.toString();

final localeName = Intl.canonicalizedLocale(name);

return initializeMessages(localeName).then((bool _) {
Intl.defaultLocale = localeName;

return AppLocalizations();
});
}

static AppLocalizations of(BuildContext context) {
return Localizations.of<AppLocalizations>(context, AppLocalizations);
}

String get title {
return Intl.message(
'This is my first localization App',
name: 'title',
);
}
}

class AppLocalizationsDelegate
extends Localizationsdelegates<AppLocalizations> {
const AppLocalizationsDelegate();

@override
bool isSupported(Locale locale) {
return ['en', 'ja'].contains(locale.languageCode);
}

@override
Future<AppLocalizations> load(Locale locale) {
return AppLocalizations.load(locale);
}

@override
bool shouldReload(AppLocalizationsDelegate old) {
return false;
}
}

Creation of .arb file: Every.arb files contains a single JSON table that maps from resource Ids to localized values. The translation is done by ARB files, that has an .arb extension. Create a folder named l10n under your lib folder. To make the intl tool to generate the .arb file, run the following command on your terminal.

flutter pub pub run intl_translation:extract_to_arb --output- dir=lib/l10n lib/localizations.dart

Above command will generate a intl_message.arb file into the lib/l10n folder, which contains a template for English language. We have to create the template translations for Japanese language based on this file. Once these files are created, we need to link the initializeMessages. To do that, we need run the command on the terminal.

The intl_en.arb file :
{
"@@last_modified": "2019-09-18T15:53:56.759403",
"title": "This is my first localization App",
"@title": {
"type": "text",
placeholders": {}
},
}
The intl_ja.arb file :
{
"@@last_modified": "これが私の最初のローカライズアプリです",
"title": "This is my first localization App",
"@title": {
"type": "text",
"placeholders": {}
},
}

The below command generates necessary messages files namely, messages_all.arb, messages_en.arb, messages_ja.arb and messages_messages.arb.

flutter pub pub run intl_translation:generate_from_arb --output-dir=lib/l10n \

--no-use-deferred-loading lib/localization.dart lib/l10n/intl_*.arb

Connecting the AppLocalizations to our MaterialApp widget: As MaterialApp is the root of Flutter App, localization setup is done here. We need to import the flutter_localization package into our main.dart file and have to initialise the supportedLocales and localizationDelegates. The supportedLocales, contain information about, list of all application supported locales and the localizationDelegates contains localization data for the selected languages. The AppLocalizations.delegate is a class that holds necessary translation files from available JSON. The GlobalMaterialLocalizations.delegate is the built-in localization for material widgets and the GlobalWidgetsLocalizations.delegate is the built-in localization for the text direction.

import'package:flutter_localizations/flutter_localizations.dart';MaterialApp(
localizationsDelegates: [
AppLocalizationsDelegate(),
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
],
supportedLocales: [
Locale('en', ""),
Locale('ja', ''),
],
home: MyHomePage(),
);

Connecting the translated text to widgets: Once every above step is done, we can just call it by of() method on AppLocalizations(), to get the instance and translate it.

class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Text(
AppLocalizations.of(context).title,
style: TextStyle(fontSize: 24),
textAlign: TextAlign.center,
),
),
);
}
}

--

--