Introduction
In the linked world of today, creating applications that can serve a worldwide audience is essential. The flexible cross-platform framework Flutter has strong localization (l10n) and internationalization (i18n) features. Developers can easily adapt their user interfaces to accommodate various languages and cultural preferences by integrating i18n and l10n into Flutter apps. This allows them to reach a wider range of users worldwide.
Understanding Internationalization and Localization.
The process of creating and building an application to make it readily adaptable to many languages, countries, and cultures is known as internationalization, or i18n. On the other hand, localization, or l10n, is the process of modifying an application to fit a particular language or geographical area. This includes things like text translations, currency symbols, date and time formats, and number formatting.
Flutter’s Internationalization Support.
Strong tools and libraries offered by Flutter make internationalisation easier. The intl
package, which provides tools for locale-specific formatting of dates, times, currencies, and messages, is the foundation of Flutter’s i18n support. This package can also be used by developers to manage language-specific text translations. Additionally, Flutter offers the flutter_localizations
package, which saves developers a great deal of time and work by providing pre-defined localisation resources for a variety of languages.
Implementing Internationalization and Localization in Flutter.
Developers must take a few crucial actions in order to enable i18n and l10n in a Flutter application. The intl
package or external localisation files should be used to define localised strings first. It is simple to translate and localise these strings for many languages. The Localisations
widget in Flutter can then be used by developers to load the appropriate localisation resources according to the user’s selected locale. Additionally, they can format dates and numbers consistently across regions by using the intl
techniques. Furthermore, several localisation settings, such language direction and text direction, are automatically handled by Flutter’s MaterialApp
and CupertinoApp
widgets.
Benefits and Challenges of Internationalization and Localization in Flutter.
Developers can gain a lot of advantages by integrating localisation and internationalisation into Flutter. By offering localised experiences that let users interact with the app in the language of their choice, they can increase the number of users. Because users feel more at ease interacting with content that is adapted to their cultural norms, localisation also improves user experience and engagement. Nevertheless, there may be difficulties in adopting i18n and l10n, including maintaining language-specific UI design, handling translation files, and making sure that each supported language is tested effectively.
A step-by-step guide on implementing internationalization and localization in Flutter:
Get Your Flutter Project Ready Make sure your Flutter project is configured and operational. Launch your project with the text editor or IDE of your choice.
Steps:
Add Dependencies In your project’s pubspec.yaml
file, add the following dependencies:
dependencies:
flutter:
sdk: flutter
flutter_localizations:
sdk: flutter
intl: any
intl_utils:
flutter:
generate: true
YAMLSave the file and run flutter pub get
to fetch the dependencies.
Define Localized Strings Create a new directory in your project’s root directory called l10n
or i18n
inside this directory create intl_en.arb file and other lan file with intl_{lamguage_code}.arb
intl_en.arb
{
"@@locale":"en",
"hello":"Hello"
}
Dartintl_hi.arb
{
"@@locale":"hi",
"hello":"नमस्ते"
}
DartRun the below command in project terminal
This command generates a .arb
file for each supported language. You can then provide translations for these files and use the intl
package to load and use them.
dart run intl_utils:generate
Import the necessary packages:
import 'package:flutter/material.dart';
import 'package:multi_lan_flutter_demo/generated/l10n.dart';
DartIn customize MaterialApp Widget
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
),
locale: Locale.fromSubtags(languageCode: localeLan.languageCode),
localizationsDelegates: [
S.delegate,
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
],
supportedLocales: S.delegate.supportedLocales,
home: HomeScreen(),
);
}
DartState Management
Add Dependencies In your project’s pubspec.yaml
file, add the following dependencies:
dependencies:
flutter:
sdk: flutter
flutter_localizations:
sdk: flutter
intl: any
intl_utils:
# The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^1.0.8
intl_translation:
shared_preferences:
# state management
flutter_bloc:
bloc:
get:
YAMLCreate Bloc Controller
import 'dart:ui';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:get/get.dart';
import 'package:get/get_core/src/get_main.dart';
import 'package:multi_lan_flutter_demo/bloc/state/app_bloc_state.dart';
import 'package:shared_preferences/shared_preferences.dart';
class AppBlocController extends Cubit<AppBlocState> {
String staticKeyForLan = "/shared/locale";
AppBlocController() : super(AppBlocState(locale: Locale('en'))) {
_initializeLocale(); // Automatically load the locale when AppBlocController is created
}
changeLocale(Locale locale) async {
var pref = await SharedPreferences.getInstance();
pref.setString(staticKeyForLan, locale.languageCode);
Get.updateLocale(Locale.fromSubtags(languageCode: locale.languageCode));
emit(state.copyWith(locale: locale));
}
Future<void> _initializeLocale() async {
var pref = await SharedPreferences.getInstance();
String lanKey = (pref.getString(staticKeyForLan)) ?? 'en';
Get.updateLocale(Locale.fromSubtags(languageCode: lanKey));
emit(state.copyWith(locale: Locale.fromSubtags(languageCode: lanKey)));
}
}
DartCreate Bloc State
import 'package:flutter/widgets.dart';
class AppBlocState {
Locale locale;
AppBlocState({required this.locale});
copyWith({Locale? locale}) {
return AppBlocState(locale: locale ?? this.locale);
}
}
DartIn main.dart create blocprovider and bloc selector to apply chnages
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:get/get.dart';
import 'package:multi_lan_flutter_demo/bloc/controller/app_bloc_controller.dart';
import 'package:multi_lan_flutter_demo/bloc/state/app_bloc_state.dart';
import 'package:multi_lan_flutter_demo/generated/l10n.dart';
import 'package:multi_lan_flutter_demo/view/home_screen.dart';
void main() {
runApp(
BlocProvider(create: (_) => AppBlocController(), child: const MyApp()),
);
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return BlocSelector<AppBlocController, AppBlocState, Locale>(
selector: (AppBlocState state) => state.locale,
builder: (BuildContext context, Locale localeLan) {
return GetMaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
),
locale: Locale.fromSubtags(languageCode: localeLan.languageCode),
localizationsDelegates: [
S.delegate,
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
],
supportedLocales: S.delegate.supportedLocales,
home: HomeScreen(),
);
},
);
}
}
DartNow, within your widget, you can listen to the AppBlocController
to change the language dynamically.
For example, in your MyHomePage
widget:
@override
Widget build(BuildContext context) {
var locale = S.of(context);
return Scaffold(
appBar: AppBar(title: Text("Intl Language Demo")),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text("${locale.hello}"),
SizedBox(height: 20),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Text("Change Language"),
Container(
decoration: BoxDecoration(
border: Border.all(color: Colors.grey[200]!),
),
child: Builder(
builder: (context) {
var items = S.delegate.supportedLocales;
return BlocSelector<
AppBlocController,
AppBlocState,
Locale
>(
selector: (AppBlocState state) => state.locale,
builder:
(BuildContext context, Locale state) =>
DropdownButton(
isDense: true,
value: state.languageCode,
items: List.generate(
items.length,
(index) => DropdownMenuItem(
value: items[index].languageCode,
child: Text(items[index].languageCode),
),
),
onChanged: (value) {
context
.read<AppBlocController>()
.changeLocale(Locale(value!));
},
),
);
},
),
),
],
),
],
),
),
);
}
DartNOTE: Get.updateLocale use only when you are using a getx in your project insted of MaterialApp Widget.
That’s it! You’ve successfully implemented internationalization and localization in your Flutter app. Remember to add more localized strings and provide translations for each language as needed.
Conclusion
Flutter’s extensive support for localisation and internationalisation enables developers to produce applications that appeal to users around the world. By adopting i18n and l10n, developers can maximise the impact and reach of their applications by removing language barriers and providing users with immersive experiences throughout the globe.