In this tutorial, we will see how to internationalize and localize your content according to language selection
As shown in below application, I am using English, Telugu and Hindi as my language content. The content is automatically loaded from language.properties file w.r.t. the user language selection.
pubspec.yaml file
name: Sample localization app description: Sample localization app. publish_to: 'none' version: 1.0.0+1 environment: sdk: ">=2.12.0 <3.0.0" dependencies: flutter: sdk: flutter flutter_localizations: sdk: flutter cupertino_icons: ^1.0.2 youtube_player_flutter: ^8.0.0 intl: ^0.17.0 provider: ^6.0.1 http: ^0.13.4 animations: ^2.0.1 convex_bottom_bar: ^3.0.0 shared_preferences: ^2.0.8 connectivity_plus: ^1.2.0 firebase_core: ^1.7.0 firebase_auth: ^3.1.2 cloud_firestore: ^2.5.3 flutter_font_icons: ^2.2.3 path: ^1.8.0 sqflite: ^2.0.0+4 dev_dependencies: flutter_test: sdk: flutter flutter_lints: ^1.0.0 flutter_launcher_icons: ^0.9.2 flutter_icons: android: true ios: true image_path: "assets/images/app_icon.png" flutter: uses-material-design: true assets: - locale/en.json - locale/te.json - locale/hin.json - assets/images/ fonts: - family: Roboto fonts: - asset: assets/fonts/Roboto-Regular.ttf - asset: assets/fonts/Roboto-Bold.ttf - asset: assets/fonts/Roboto-Medium.ttf - asset: assets/fonts/Roboto-Thin.ttf weight: 700
en.json
{ "APP_TITLE":"Sample Locale APP", "GREETING":"Hi Hello Jayaram!!!" }
te.json(Telugu)
{ "APP_TITLE":"టెస్తింగ్ ఆప్", "GREETING":"హెల్లౌ జయరం" }
hi.json (Hindi Language)
{ "APP_TITLE":"Hindhi Testing APP", "GREETING":"Hindhi text greeting" }
locale_provider.dart
import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; class AppLocale with ChangeNotifier { Locale? _locale = Locale("te", "IN"); Locale? get locale => _locale; void setLocale(Locale locale) { _locale = locale; notifyListeners(); } }
main.dart
import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter/foundation.dart'; import 'package:provider/provider.dart'; import './model/auth.dart'; import './screens/signup_screen.dart'; import '../util/app_theme.dart'; import 'package:flutter_localizations/flutter_localizations.dart'; import './localization/app_translation.dart'; import './model/locale_provider.dart'; void main() async { WidgetsFlutterBinding.ensureInitialized(); await SystemChrome.setPreferredOrientations(<DeviceOrientation>[ DeviceOrientation.portraitUp, DeviceOrientation.portraitDown ]).then((_) => runApp(MyApp())); } class MyApp extends StatefulWidget { const MyApp({Key? key}) : super(key: key); @override _MyAppState createState() => _MyAppState(); } class _MyAppState extends State<MyApp> { late AppLocalizationsDelegate localizationsDelegate; Locale locale = Locale("te", "IN"); @override void initState() { localizationsDelegate = AppLocalizationsDelegate(locale); super.initState(); } @override Widget build(BuildContext context) { return MultiProvider( providers: [ ChangeNotifierProvider(create: (ctx) => UserAuthentication()), ChangeNotifierProvider(create: (ctx) => AppLocale()), ], child: Consumer<AppLocale>(builder: (context, provider, snapshot) { return MaterialApp( locale: provider.locale, title: "Sample Localization App", localizationsDelegates: [ GlobalMaterialLocalizations.delegate, GlobalWidgetsLocalizations.delegate, GlobalCupertinoLocalizations.delegate, localizationsDelegate, ], supportedLocales: [ const Locale('en', 'IN'), const Locale('te', 'IN'), ], localeResolutionCallback: (loc, supportedLocales) { // Check if the current device locale is supported for (var supportedLocale in supportedLocales) { if (supportedLocale.languageCode == loc?.languageCode && supportedLocale.countryCode == loc?.countryCode) { return supportedLocale; } } // If the locale of the device is not supported, use the first one // from the list (English, in this case). return supportedLocales.first; }, theme: AppTheme, initialRoute: "/", routes: {'/': (content) => const LoginScreen()}, ); })); } }
app_transalation.dart => AppLocalizations, AppLocalizationsDelagate
import 'dart:async'; import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; class AppLocalizations { AppLocalizations(this.locale); final Locale locale; static Map<String, dynamic> localizedValues = {}; static AppLocalizations of(BuildContext context) { return Localizations.of<AppLocalizations>(context, AppLocalizations)!; } Future<bool> load() async { // Load the language JSON file from the "lang" folder String jsonString = await rootBundle.loadString('locale/${locale.languageCode}.json'); Map<String, dynamic> jsonMap = json.decode(jsonString); localizedValues = jsonMap.map((key, value) { return MapEntry(key, value.toString()); }); return true; } String translate(String key) { return localizedValues[key]; } } class AppLocalizationsDelegate extends LocalizationsDelegate<AppLocalizations> { final Locale locale; AppLocalizationsDelegate(this.locale); final List<String> supportedLanguagesCodes = [ "en", // English "te", //telugu 'hi' // hindi ]; @override bool isSupported(Locale locale) { return supportedLanguagesCodes.contains(locale.languageCode); } @override Future<AppLocalizations> load(Locale locale) async { AppLocalizations localizations = AppLocalizations(locale); await localizations.load(); return localizations; } @override bool shouldReload(AppLocalizationsDelegate old) => true; }
signup_screen.dart
import 'package:flutter/material.dart'; import '../localization/app_translation.dart'; import 'package:provider/provider.dart'; import '../model/locale_provider.dart'; class LoginScreen extends StatelessWidget { const LoginScreen({Key? key}) : super(key: key); static final List<Locale> supportedLanguagesCodes = [ Locale("en", "IN"), Locale("te", "IN"), ]; @override Widget build(BuildContext context) { var lang = Provider.of<AppLocale>(context); _title(String val) { switch (val) { case 'en': return Text( 'English', style: TextStyle(fontSize: 16.0), ); case 'te': return Text( 'telugu', style: TextStyle(fontSize: 16.0), ); default: return Text( 'English', style: TextStyle(fontSize: 16.0), ); } } return Scaffold( appBar: AppBar( title: Text(AppLocalizations.of(context).translate("APP_TITLE")), ), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Text( AppLocalizations.of(context).translate("GREETING"), style: TextStyle( fontSize: 20.0, fontWeight: FontWeight.w500, ), ), SizedBox(height: 85.0), DropdownButton( value: lang.locale, onChanged: (Locale? val) { lang.setLocale(val!); }, items: supportedLanguagesCodes .map((e) => DropdownMenuItem( value: e, child: _title(e.languageCode), )) .toList()) ], ), ), ); } }