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: