In Flutter development, creating apps that cater to a global audience requires robust internationalization (i18n) and localization (l10n) support. The intl
package in Flutter is a powerful tool designed to handle translations, number formatting, date formatting, and more, ensuring your app is accessible to users around the world. This comprehensive guide walks you through the process of using the intl
package to manage translations effectively in your Flutter application.
What is the intl
Package?
The intl
package is a part of the Flutter ecosystem that provides internationalization and localization facilities. It includes APIs for:
- Message Translation: Localizing text and messages.
- Date and Time Formatting: Displaying dates and times according to locale-specific conventions.
- Number Formatting: Formatting numbers, currencies, and percentages for different regions.
- Pluralization: Handling different forms of text based on quantity.
Why Use the intl
Package?
- Globalization: Supports creating apps for a worldwide audience.
- Easy Translation Management: Provides tools to manage translations efficiently.
- Standardization: Follows international standards for date, time, and number formatting.
- Integration: Seamlessly integrates with Flutter’s localization framework.
Setting Up the intl
Package in Flutter
Step 1: Add the intl
Package to pubspec.yaml
Add the intl
package to your pubspec.yaml
file under the dependencies
section:
dependencies:
flutter:
sdk: flutter
intl: ^0.18.1
Then, run flutter pub get
in your terminal to install the package.
Step 2: Configure the Application for Localization
In your main.dart
file, configure your Flutter application for localization:
import 'package:flutter/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:intl/intl.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Intl Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
localizationsDelegates: [
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
],
supportedLocales: [
const Locale('en', 'US'), // English, United States
const Locale('es', 'ES'), // Spanish, Spain
],
home: MyHomePage(),
);
}
}
class MyHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Flutter Intl Demo'),
),
body: Center(
child: Text(
Intl.message(
'Hello, World!',
name: 'helloWorld',
desc: 'The conventional greeting',
),
),
),
);
}
}
Explanation:
flutter_localizations
is imported to provide localized values for the core Flutter widgets.localizationsDelegates
specify how the app should handle localization.supportedLocales
define the locales your app supports.
Managing Translations with intl
Step 1: Create an l10n.yaml
File
Create an l10n.yaml
file in the root of your Flutter project to configure the localization settings:
arb-dir: lib/l10n
template-arb-file: app_en.arb
output-localization-file: app_localizations.dart
This configuration tells Flutter where to find the ARB (Application Resource Bundle) files and where to output the generated localization file.
Step 2: Create ARB Files
Create ARB files in the lib/l10n
directory for each supported locale. The template ARB file (e.g., app_en.arb
) is the base translation file.
app_en.arb
(English)
{
"@@locale": "en",
"helloWorld": "Hello, World!",
"@helloWorld": {
"description": "The conventional greeting"
},
"welcomeMessage": "Welcome to our app, {userName}!",
"@welcomeMessage": {
"description": "A personalized welcome message",
"placeholders": {
"userName": {
"type": "String",
"example": "John Doe"
}
}
},
"itemCount": "{count,plural, =0{No items} =1{One item} other{{count} items}}" ,
"@itemCount": {
"description": "Shows the number of items in a list",
"placeholders": {
"count": {
"type": "int",
"example": "3"
}
}
}
}
app_es.arb
(Spanish)
{
"@@locale": "es",
"helloWorld": "¡Hola, Mundo!",
"@helloWorld": {
"description": "El saludo convencional"
},
"welcomeMessage": "¡Bienvenido a nuestra aplicación, {userName}!",
"@welcomeMessage": {
"description": "Un mensaje de bienvenida personalizado",
"placeholders": {
"userName": {
"type": "String",
"example": "Juan Pérez"
}
}
},
"itemCount": "{count,plural, =0{No hay elementos} =1{Un elemento} other{{count} elementos}}",
"@itemCount": {
"description": "Muestra el número de elementos en una lista",
"placeholders": {
"count": {
"type": "int",
"example": "3"
}
}
}
}
Step 3: Generate the Localization File
Run the following command in your terminal to generate the app_localizations.dart
file:
flutter gen-l10n
Step 4: Use the Generated Localization in Your App
Import the generated app_localizations.dart
file and use it to access the translated messages:
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
class MyHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(AppLocalizations.of(context)!.helloWorld),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
AppLocalizations.of(context)!.helloWorld,
style: TextStyle(fontSize: 20),
),
SizedBox(height: 20),
Text(
AppLocalizations.of(context)!.welcomeMessage('John Doe'),
style: TextStyle(fontSize: 20),
),
SizedBox(height: 20),
Text(
AppLocalizations.of(context)!.itemCount(3),
style: TextStyle(fontSize: 20),
)
],
),
),
);
}
}
Formatting Dates and Numbers
Date Formatting
Use DateFormat
from the intl
package to format dates and times according to locale-specific conventions:
import 'package:intl/intl.dart';
String formatDate(DateTime date, Locale locale) {
final formatter = DateFormat.yMMMd(locale.toString());
return formatter.format(date);
}
Number Formatting
Use NumberFormat
to format numbers, currencies, and percentages:
import 'package:intl/intl.dart';
String formatCurrency(double amount, Locale locale) {
final formatter = NumberFormat.currency(locale: locale.toString(), symbol: '$');
return formatter.format(amount);
}
String formatNumber(int number, Locale locale) {
final formatter = NumberFormat.decimalPattern(locale.toString());
return formatter.format(number);
}
Handling Pluralization
The intl
package supports pluralization, allowing you to display different text based on quantity. As seen in the ARB file example, you can use the plural format directly in your translation files.
{
"itemCount": "{count,plural, =0{No items} =1{One item} other{{count} items}}"
}
In your Dart code, call the localized string with the count:
Text(AppLocalizations.of(context)!.itemCount(itemCount))
Switching Locales Dynamically
To allow users to switch locales within your app, you can use the setState
method in a stateful widget to update the locale:
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
class LocaleSwitcher extends StatefulWidget {
@override
_LocaleSwitcherState createState() => _LocaleSwitcherState();
}
class _LocaleSwitcherState extends State {
Locale _currentLocale = Locale('en', 'US');
void _changeLocale(Locale newLocale) {
setState(() {
_currentLocale = newLocale;
});
}
@override
Widget build(BuildContext context) {
return MaterialApp(
localizationsDelegates: [
AppLocalizations.delegate,
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
],
supportedLocales: [
const Locale('en', 'US'),
const Locale('es', 'ES'),
],
locale: _currentLocale,
home: Scaffold(
appBar: AppBar(
title: Text(AppLocalizations.of(context)?.helloWorld ?? 'Hello, World!'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
AppLocalizations.of(context)?.welcomeMessage('User') ?? 'Welcome, User!',
style: TextStyle(fontSize: 20),
),
SizedBox(height: 20),
DropdownButton(
value: _currentLocale,
items: [
DropdownMenuItem(
child: Text('English'),
value: Locale('en', 'US'),
),
DropdownMenuItem(
child: Text('Español'),
value: Locale('es', 'ES'),
),
],
onChanged: (Locale? locale) {
if (locale != null) {
_changeLocale(locale);
}
},
),
],
),
),
),
);
}
}
Conclusion
The intl
package in Flutter provides comprehensive tools for internationalization and localization, enabling you to create apps that cater to a global audience. By setting up the intl
package, managing translations with ARB files, and formatting dates and numbers, you can ensure your app is accessible and user-friendly for people around the world. Effective use of the intl
package enhances the user experience and expands the reach of your Flutter application.