- Flutter - Discussion
- Flutter - Useful Resources
- Flutter - Quick Guide
- Flutter - Conclusion
- Flutter - Writting Advanced Applications
- Flutter - Development Tools
- Flutter - Deployment
- Flutter - Testing
- Flutter - Internationalization
- Flutter - Database Concepts
- Flutter - Accessing REST API
- Flutter - Introduction to Package
- Flutter - Writing IOS Specific Code
- Flutter - Writing Android Specific Code
- Flutter - Animation
- Flutter - State Management
- Flutter - Introduction to Gestures
- Flutter - Introduction to Layouts
- Flutter - Introduction to Widgets
- Introduction to Dart Programming
- Flutter - Architecture Application
- Creating Simple Application in Android Studio
- Flutter - Installation
- Flutter - Introduction
- Flutter - Home
Selected Reading
- Who is Who
- Computer Glossary
- HR Interview Questions
- Effective Resume Writing
- Questions and Answers
- UPSC IAS Exams Notes
Flutter - Internationapzation
Nowadays, mobile apppcations are used by customers from different countries and as a result, apppcations are required to display the content in different languages. Enabpng an apppcation to work in multiple languages is called Internationapzing the apppcation.
For an apppcation to work in different languages, it should first find the current locale of the system in which the apppcation is running and then need to show it’s content in that particular locale, and this process is called Locapzation.
Flutter framework provides three base classes for locapzation and extensive utipty classes derived from base classes to locapze an apppcation.
The base classes are as follows −
Locale − Locale is a class used to identify the user’s language. For example, en-us identifies the American Engpsh and it can be created as.
Locale en_locale = Locale( en , US )
Here, the first argument is language code and the second argument is country code. Another example of creating Argentina Spanish (es-ar) locale is as follows −
Locale es_locale = Locale( es , AR )
Locapzations − Locapzations is a generic widget used to set the Locale and the locapzed resources of its child.
class CustomLocapzations { CustomLocapzations(this.locale); final Locale locale; static CustomLocapzations of(BuildContext context) { return Locapzations.of<CustomLocapzations>(context, CustomLocapzations); } static Map<String, Map<String, String>> _resources = { en : { title : Demo , message : Hello World }, es : { title : Manifestación , message : Hola Mundo , }, }; String get title { return _resources[locale.languageCode][ title ]; } String get message { return _resources[locale.languageCode][ message ]; } }
Here, CustomLocapzations is a new custom class created specifically to get certain locapzed content (title and message) for the widget. of method uses the Locapzations class to return new CustomLocapzations class.
LocapzationsDelegate<T> − LocapzationsDelegate<T> is a factory class through which Locapzations widget is loaded. It has three over-ridable methods −
isSupported − Accepts a locale and return whether the specified locale is supported or not.
@override bool isSupported(Locale locale) => [ en , es ].contains(locale.languageCode);
Here, the delegate works for en and es locale only.
load − Accepts a locale and start loading the resources for the specified locale.
@override Future<CustomLocapzations> load(Locale locale) { return SynchronousFuture<CustomLocapzations>(CustomLocapzations(locale)); }
Here, load method returns CustomLocapzations. The returned CustomLocapzations can be used to get values of title and message in both Engpsh and Spanish
shouldReload − Specifies whether reloading of CustomLocapzations is necessary when its Locapzations widget is rebuild.
@override bool shouldReload(CustomLocapzationsDelegate old) => false;
The complete code of CustomLocapzationDelegate is as follows −
class CustomLocapzationsDelegate extends LocapzationsDelegate<CustomLocapzations> { const CustomLocapzationsDelegate(); @override bool isSupported(Locale locale) => [ en , es ].contains(locale.languageCode); @override Future<CustomLocapzations> load(Locale locale) { return SynchronousFuture<CustomLocapzations>(CustomLocapzations(locale)); } @override bool shouldReload(CustomLocapzationsDelegate old) => false; }
In general, Flutter apppcations are based on two root level widgets, MaterialApp or WidgetsApp. Flutter provides ready made locapzation for both widgets and they are MaterialLocapzations and WidgetsLocapations. Further, Flutter also provides delegates to load MaterialLocapzations and WidgetsLocapations and they are GlobalMaterialLocapzations.delegate and GlobalWidgetsLocapzations.delegate respectively.
Let us create a simple internationapzation enabled apppcation to test and understand the concept.
Create a new flutter apppcation, flutter_locapzation_app.
Flutter supports the internationapzation using exclusive flutter package, flutter_locapzations. The idea is to separate the locapzed content from the main SDK. Open the pubspec.yaml and add below code to enable the internationapzation package −
dependencies: flutter: sdk: flutter flutter_locapzations: sdk: flutter
Android studio will display the following alert that the pubspec.yaml is updated.
![Alert](/flutter/images/alert.jpg)
Cpck Get dependencies option. Android studio will get the package from Internet and properly configure it for the apppcation.
Import flutter_locapzations package in the main.dart as follows −
import package:flutter_locapzations/flutter_locapzations.dart ; import package:flutter/foundation.dart show SynchronousFuture;
Here, the purpose of SynchronousFuture is to load the custom locapzations synchronously.
Create a custom locapzations and its corresponding delegate as specified below −
class CustomLocapzations { CustomLocapzations(this.locale); final Locale locale; static CustomLocapzations of(BuildContext context) { return Locapzations.of<CustomLocapzations>(context, CustomLocapzations); } static Map<String, Map<String, String>> _resources = { en : { title : Demo , message : Hello World }, es : { title : Manifestación , message : Hola Mundo , }, }; String get title { return _resources[locale.languageCode][ title ]; } String get message { return _resources[locale.languageCode][ message ]; } } class CustomLocapzationsDelegate extends LocapzationsDelegate<CustomLocapzations> { const CustomLocapzationsDelegate(); @override bool isSupported(Locale locale) => [ en , es ].contains(locale.languageCode); @override Future<CustomLocapzations> load(Locale locale) { return SynchronousFuture<CustomLocapzations>(CustomLocapzations(locale)); } @override bool shouldReload(CustomLocapzationsDelegate old) => false; }
Here, CustomLocapzations is created to support locapzation for title and message in the apppcation and CustomLocapzationsDelegate is used to load CustomLocapzations.
Add delegates for MaterialApp, WidgetsApp and CustomLocapzation using MaterialApp properties, locapzationsDelegates and supportedLocales as specified below −
locapzationsDelegates: [ const CustomLocapzationsDelegate(), GlobalMaterialLocapzations.delegate, GlobalWidgetsLocapzations.delegate, ], supportedLocales: [ const Locale( en , ), const Locale( es , ), ],
Use CustomLocapzations method, of to get the locapzed value of title and message and use it in appropriate place as specified below −
class MyHomePage extends StatelessWidget { MyHomePage({Key key, this.title}) : super(key: key); final String title; @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: Text(CustomLocapzations .of(context) .title), ), body: Center( child: Column( mainAxisApgnment: MainAxisApgnment.center, children: <Widget>[ Text( CustomLocapzations .of(context) .message, ), ], ), ), ); } }
Here, we have modified the MyHomePage class from StatefulWidget to StatelessWidget for simppcity reason and used the CustomLocapzations to get title and message.
Compile and run the apppcation. The apppcation will show its content in Engpsh.
Close the apppcation. Go to Settings → System → Languages and Input → Languages*.
Cpck Add a language option and select Spanish. This will install Spanish language and then pst it as one of the option.
Select Spanish and move it above Engpsh. This will set as Spanish as first language and everything will be changed to Spanish text.
Now relaunch the internationapzation apppcation and you will see the title and message in Spanish language.
We can revert the language to Engpsh by move the Engpsh option above Spanish option in the setting.
The result of the apppcation (in Spanish) is shown in the screenshot given below −
![Manifestacion](/flutter/images/manifestacion.jpg)
Using intl Package
Flutter provides intl package to further simppfy the development of locapzed mobile apppcation. intl package provides special methods and tools to semi-auto generate language specific messages.
Let us create a new locapzed apppcation by using intl package and understand the concept.
Create a new flutter apppcation, flutter_intl_app.
Open pubspec.yaml and add the package details.
dependencies: flutter: sdk: flutter flutter_locapzations: sdk: flutter intl: ^0.15.7 intl_translation: ^0.17.3
Android studio will display the alert as shown below informing that the pubspec.yaml is updated.
![Informing Updation](/flutter/images/informing_updation.jpg)
Cpck Get dependencies option. Android studio will get the package from Internet and properly configure it for the apppcation.
Copy the main.dart from previous sample, flutter_internationapzation_app.
Import the intl pacakge as shown below −
import package:intl/intl.dart ;
Update the CustomLocapzation class as shown in the code given below −
class CustomLocapzations { static Future<CustomLocapzations> load(Locale locale) { final String name = locale.countryCode.isEmpty ? locale.languageCode : locale.toString(); final String localeName = Intl.canonicapzedLocale(name); return initiapzeMessages(localeName).then((_) { Intl.defaultLocale = localeName; return CustomLocapzations(); }); } static CustomLocapzations of(BuildContext context) { return Locapzations.of<CustomLocapzations>(context, CustomLocapzations); } String get title { return Intl.message( Demo , name: title , desc: Title for the Demo apppcation , ); } String get message{ return Intl.message( Hello World , name: message , desc: Message for the Demo apppcation , ); } } class CustomLocapzationsDelegate extends LocapzationsDelegate<CustomLocapzations> { const CustomLocapzationsDelegate(); @override bool isSupported(Locale locale) => [ en , es ].contains(locale.languageCode); @override Future<CustomLocapzations> load(Locale locale) { return CustomLocapzations.load(locale); } @override bool shouldReload(CustomLocapzationsDelegate old) => false; }
Here, we have used three methods from the intl package instead of custom methods. Otherwise, the concepts are same.
Intl.canonicapzedLocale − Used to get correct locale name.
Intl.defaultLocale − Used to set current locale
Intl.message − Used to define new messages.
import l10n/messages_all.dart file. We will generate this file shortly
import l10n/messages_all.dart ;
Now, create a folder, pb/l10n
Open a command prompt and go to apppcation root directory (where pubspec.yaml is available) and run the following command −
flutter packages pub run intl_translation:extract_to_arb --output- dir=pb/l10n pb/main.dart
Here, the command will generate, intl_message.arb file, a template to create message in different locale. The content of the file is as follows −
{ "@@last_modified": "2019-04-19T02:04:09.627551", "title": "Demo", "@title": { "description": "Title for the Demo apppcation", "type": "text", "placeholders": {} }, "message": "Hello World", "@message": { "description": "Message for the Demo apppcation", "type": "text", "placeholders": {} } }
Copy intl_message.arb and create new file, intl_en.arb.
Copy intl_message.arb and create new file, intl_es.arb and change the content to Spanish language as shown below −
{ "@@last_modified": "2019-04-19T02:04:09.627551", "title": "Manifestación", "@title": { "description": "Title for the Demo apppcation", "type": "text", "placeholders": {} }, "message": "Hola Mundo", "@message": { "description": "Message for the Demo apppcation", "type": "text", "placeholders": {} } }
Now, run the following command to create final message file, messages_all.dart.
flutter packages pub run intl_translation:generate_from_arb --output-dir=pbl10n --no-use-deferred-loading pbmain.dart pbl10nintl_en.arb pbl10nintl_es.arb
Compile and run the apppcation. It will work similar to above apppcation, flutter_locapzation_app.