Mastering Flutter Localization Building

 

Flutter's application Localizations


Create Multilingual Flutter App

In today's globalized world, building apps that cater to users from diverse linguistic backgrounds is no longer just an option; it's a necessity. Whether you're developing a simple utility app or a complex enterprise solution, ensuring that your app speaks the language of your users can significantly enhance user experience and engagement.

One of the most popular frameworks for building cross-platform mobile applications is Flutter. Flutter provides a rich set of tools and libraries for developing beautiful and performant apps, and it also offers robust support for localization and internationalization out of the box.

In this comprehensive guide, we'll dive deep into Flutter localization, exploring everything from setting up your project for multilingual support to implementing dynamic language switching within your app. By the end of this guide, you'll be equipped with the knowledge and skills to create multilingual Flutter apps that resonate with users worldwide.

So, without further ado, let's embark on our journey to mastering Flutter localization!

Below is visual demo:




Setting Up Your Project

Before we delve into the intricacies of Flutter localization, let's ensure that our project is properly configured to support multilingualism. The first step involves adding the necessary dependencies to our pubspec.yaml file:

dependencies:
  flutter:
    sdk: flutter

  flutter_localizations:
    sdk: flutter

  cupertino_icons: ^1.0.2
  flutter_localization: ^0.2.0

The flutter_localizations package is essential for providing Flutter with built-in localization support, while flutter_localization simplifies the process of managing localized strings within our app.

Understanding the Code

Now that we've set up our project, let's dissect the provided code block by block to gain a deeper understanding of how Flutter localization works.

applocalizationdelegate.dart
import 'package:flutter/material.dart';
import 'package:localizationdemo/localization/string_es.dart';
import 'package:localizationdemo/localization/string_en.dart';

class AppLocalizations {
  final Locale locale;

  AppLocalizations(this.locale);

  static Map<String, Map<String, String>> _localizedValues = {
    'en': englishStrings,
    'es': spanishStrings,
  };

  String? translate(String key) {
    return _localizedValues[locale.languageCode]?[key];
  }

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

AppLocalizations Class: This class encapsulates the functionality for retrieving localized strings based on the current locale. It contains a constructor that takes a Locale object as a parameter, allowing us to initialize the class with the desired language.

_localizedValues Map: This static map stores the localized strings for different languages. The keys represent language codes (e.g., 'en' for English, 'es' for Spanish), and the values are maps containing key-value pairs of string identifiers and their corresponding translations.

translate Method: This method takes a string key as input and returns the translated string based on the current locale. It retrieves the appropriate translation from _localizedValues based on the language code of the current locale.

of Method: This static method provides a convenient way to access an instance of AppLocalizations within the widget tree. It uses Flutter's Localizations.of method to retrieve the nearest AppLocalizations instance from the widget hierarchy.

applocalizationdelegate.dart
class AppLocalizationDelegate extends LocalizationsDelegate<AppLocalizations>{
  const AppLocalizationDelegate();
  
  @override
  bool isSupported(Locale locale) {
    return ['en','es'].contains(locale.languageCode);
  }

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

  @override
  bool shouldReload(covariant LocalizationsDelegate<AppLocalizations> old) {
    return false;
  }
}

AppLocalizationDelegate Class: This class extends LocalizationsDelegate and serves as the delegate responsible for loading and providing instances of AppLocalizations based on the requested locale.

isSupported Method: This method determines whether a given locale is supported by the app. In this case, it checks if the language code of the locale is either 'en' (English) or 'es' (Spanish) and returns true if it is.

load Method: This method loads an instance of AppLocalizations for the specified locale. It is invoked when a new locale is requested, and it returns a future that resolves to an instance of AppLocalizations initialized with the requested locale.

shouldReload Method: This method indicates whether the delegate should reload its localization data when the app's localization state changes. Since our localization data is static and does not change at runtime, we always return false to prevent unnecessary reloading.

string_en.dart and string_es.dart


These files contain simple maps (englishStrings and spanishStrings) that map string keys to their respective translations in English and Spanish.

Map<String, String> englishStrings = {
  'helloworld': 'Hello World',
  'medicine' : 'Medicine',
  'hospital' : 'Hospital'
};

Map<String, String> spanishStrings = {
  'helloworld': '¡Hola, Mundo!',
  'medicine':'Medicina',
  'hospital':'Hospital'
};

localization_screen.dart

import 'package:flutter/material.dart';
import 'localization/applocalizationsdelegate.dart';

class LocalizationScreen extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return LocalizationScreenState();
  }
}

class LocalizationScreenState extends State<LocalizationScreen> {
  Locale _currentLocale = Locale('en');

  void _changeLanguage(Locale locale) {
    setState(() {
      _currentLocale = locale;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Padding(
        padding: const EdgeInsets.all(20.0),
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          crossAxisAlignment: CrossAxisAlignment.center,
          children: [
            Text(
              'Localization Demo in ' + _currentLocale.languageCode,
              style: TextStyle(color: Colors.black, fontSize: 20),
            ),
            SizedBox(height: 20),
            Text(
              AppLocalizations(_currentLocale).translate('medicine') ?? '',
              style: TextStyle(color: Colors.black),
            ),
            Text(
              AppLocalizations(_currentLocale).translate('hospital') ?? '',
              style: TextStyle(color: Colors.black),
            ),
            Text(
              AppLocalizations(_currentLocale).translate('helloworld') ?? '',
              style: TextStyle(color: Colors.black),
            ),
            SizedBox(height: 20),
            ElevatedButton(
              onPressed: () {
                _changeLanguage(Locale('en'));
              },
              child: Text('English'),
            ),
            SizedBox(height: 10),
            ElevatedButton(
              onPressed: () {
                _changeLanguage(Locale('es'));
              },
              child: Text('Spanish'),
            ),
          ],
        ),
      ),
    );
  }
}

LocalizationScreen Class: This StatefulWidget represents the screen where localization is demonstrated. It maintains the current locale state and provides buttons to switch between English and Spanish languages.

_changeLanguage Method: This method is called when the user selects a different language. It updates the _currentLocale state with the newly selected locale, triggering a rebuild of the widget tree with the updated localization.

build Method: This method defines the layout of the LocalizationScreen widget. It displays the current language code, as well as translated strings for 'medicine', 'hospital', and 'helloworld'. It also provides buttons to switch between English and Spanish languages.

main.dart

import 'package:flutter/material.dart';
import 'package:flutter_localization/flutter_localization.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:localizationdemo/localization/string_en.dart' as en;
import 'package:localizationdemo/localization/string_es.dart' as es;
import 'package:localizationdemo/localization_screen.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      supportedLocales: [
        Locale('en', 'EN'),
        Locale('es', 'ES'),
      ],
      localizationsDelegates: [
        GlobalMaterialLocalizations.delegate,
        GlobalWidgetsLocalizations.delegate,
        AppLocalizationDelegate(),
      ],
      home: LocalizationScreen(),
    );
  }
}

MyApp Class: This StatelessWidget represents the root of the Flutter application. It configures the MaterialApp with the app's title, theme, supported locales, and localization delegates.

supportedLocales: This property specifies the list of supported locales for the app. It includes both English and Spanish locales, each with a language code and a country code.

localizationsDelegates: This property defines the list of localization delegates used by the app. In addition to the default delegates for Material and widgets localization, we include our custom AppLocalizationDelegate to handle app-specific localization.

home: This property sets the initial route for the app, which in this case is the LocalizationScreen widget.

Conclusion

Congratulations on reaching the end of this extensive guide on Flutter localization! We've covered everything you need to know to implement multilingual support in your Flutter apps, from setting up the project to dynamically switching between languages.

By leveraging Flutter's powerful localization features and following best practices, you can create apps that resonate with users from diverse linguistic backgrounds, thereby expanding your app's reach and impact.

As you continue your journey with Flutter development, remember to prioritize localization as an integral part of your app's development process. By making your app accessible to users worldwide, you not only enhance user experience but also foster inclusivity and diversity in the digital landscape.

Happy coding, and may your Flutter apps speak the language of success! 🚀

Comments

Popular posts from this blog

Push Notifications in .NET MAUI: A Comprehensive Guide

Explore the UI libraries available for .NET MAUI at no cost.

Push Notification using Firebase in xamarin form (Android and IOS)