Flutter - Get Device Language (Locale) Examples

This tutorial shows you how to get the device language or locale using Flutter.

If you develop an application, you may need to detect what is the language or locale used by the device. Especially if the application supports multi-language. By doing so, the application can automatically use the most suitable locale according to the device. This tutorial includes how to enable localization in a Flutter application, how to get the language code and locale code, as well as how to detect locale change.

Enable Flutter Localization

Flutter has a Locale class by which you can get the country code and language code (such as en-US, en-UK, es-ES). It's possible to get the current locale from the BuildContext. However, a Flutter application only supports English (United States) (en-US) locale by default. Therefore, even if the device uses another language, if the device language is not supported by the Flutter application, you'll get the default locale which is en-US.

As a result, you need to make the Flutter application supports localization and set the list of allowed locales. First of all, add flutter_localizations to the pubspec.yaml file, right under the dependencies key.

  dependencies:
    flutter_localizations:
      sdk: flutter

Then, run the flutter pub get command. The next thing you need to do is adding the list of localizationsDelegates to the MaterialApp. The passed elements are factories for producing localized values. GlobalMaterialLocalizations.delegate is used to provide localized strings and other values for the Material Components library. For supporting different text directions, you need to add GlobalWidgetsLocalizations.delegate. You also need GlobalCupertinoLocalizations.delegate to support Cupertino widgets.

In the MaterialWidget constructor, you also need to add the supportedLocales argument in order to replace the default value which only supports en-US.

  return const MaterialApp(
    title: 'Woolha.com Flutter Tutorial',
    home: GetDeviceLocale(),
    localizationsDelegates: [
      GlobalMaterialLocalizations.delegate,
      GlobalWidgetsLocalizations.delegate,
      GlobalCupertinoLocalizations.delegate,
    ],
    supportedLocales: [
      Locale('en', 'US'),
      Locale('id', 'ID')
    ],
  );

Get Device Locale

To get the locale of the device, you can call the below static method by passing the current BuildContext.

  static Locale localeOf(BuildContext context)

Below is the usage example.

  final Locale locale = Localizations.localeOf(context);

From the Locale instance, you can access the languageCode and countryCode properties.

  locale.languageCode
  locale.countryCode

Detect Locale Change

A user can change the used language or locale of his device anytime. If your application needs to detect events when the locale is changed, it's a possible thing in Flutter.

What you need to do is to create a State class that uses the WidgetsBindingObserver interface. It has a method named didChangeLocales which is called when the system tells the app that the user's locale has changed. The method has an argument locales which contains the list of current locales of the device. To use WidgetsBindingObserver, you have to call addObserver inside the initState method to register the class as a binding observer. Then, call removeObserver inside the dispose method to unregister the observer.

  class _GetDeviceLocaleState extends State<GetDeviceLocale>
      with WidgetsBindingObserver {
  
    Locale? _locale;
  
    @override
    void initState() {
      WidgetsBinding.instance.addObserver(this);
      super.initState();
  
      WidgetsBinding.instance
          .addPostFrameCallback((_) => setLocale(context));
    }
  
    @override
    void dispose() {
      WidgetsBinding.instance.removeObserver(this);
      super.dispose();
    }
  
    @override
    void didChangeLocales(List<Locale>? locales) {
      super.didChangeLocales(locales);
  
      setState(() {
        _locale = locales?.first ?? _locale;
      });
    }
  }

Full Code

  import 'package:flutter/material.dart';
  import 'package:flutter_localizations/flutter_localizations.dart';
  
  void main() => runApp(const MyApp());
  
  class MyApp extends StatelessWidget {
  
    const MyApp({Key? key}) : super(key: key);
  
    @override
    Widget build(BuildContext context) {
      return const MaterialApp(
        title: 'Woolha.com Flutter Tutorial',
        home: GetDeviceLocale(),
        localizationsDelegates: [
          GlobalMaterialLocalizations.delegate,
          GlobalWidgetsLocalizations.delegate,
          GlobalCupertinoLocalizations.delegate,
        ],
        supportedLocales: [
          Locale('en', 'US'),
          Locale('id', 'ID')
        ],
      );
    }
  }
  
  class GetDeviceLocale extends StatefulWidget {
  
    const GetDeviceLocale({Key? key}) : super(key: key);
  
    @override
    State<StatefulWidget> createState() {
      return _GetDeviceLocaleState();
    }
  }
  
  class _GetDeviceLocaleState extends State<GetDeviceLocale>
      with WidgetsBindingObserver {
  
    Locale? _locale;
  
    @override
    void initState() {
      WidgetsBinding.instance.addObserver(this);
      super.initState();
  
      WidgetsBinding.instance
          .addPostFrameCallback((_) => setLocale(context));
    }
  
    @override
    void dispose() {
      WidgetsBinding.instance.removeObserver(this);
      super.dispose();
    }
  
    @override
    void didChangeLocales(List<Locale>? locales) {
      super.didChangeLocales(locales);
  
      setState(() {
        _locale = locales?.first ?? _locale;
      });
    }
  
    setLocale(BuildContext context) {
      final Locale locale = Localizations.localeOf(context);
  
      setState(() {
        _locale = locale;
      });
    }
  
    @override
    Widget build(BuildContext context) {
      return Scaffold(
        appBar: AppBar(
          title: const Text('Woolha.com Flutter Tutorial'),
          backgroundColor: Colors.teal,
        ),
        body: SizedBox(
          width: double.infinity,
          child: Center(
            child: Text('Locale: ${_locale?.languageCode}-${_locale?.countryCode}'),
          ),
        ),
      );
    }
  }

Summary

To detect the language or locale using Flutter, you need to make the Flutter application supports localization. Then, you can get the current locale by calling Localizations.localeOf(context). If you want to detect locale changes, use the WidgetsBindingObserver interface and override the didChangeLocales method.

You can also read about: