preface
For detailed information about internationalization of FLUTTER, you can go to the Internationalization of Flutter App
This article focuses on how Flutter is multilingual and how to use multiple languages ($T) and implement language switches just like the Web uses I18N, which is more user-friendly for front-end developers.
The project address
Flutter – UI, an open source project containing an introduction to flutter components, welcomes Star
Flutter_intl This tutorial project source, welcome star
The effect
How to use
Add the dependent
- Introduce dependencies in pubspec.yaml
dependencies:
flutter_localizations:
sdk: flutter
Copy the code
- perform
flutter packages get
Copy the code
New file Locale
locale
|-en.json
|-zh.json
Copy the code
Multilingual files
- en.json
{
"title_page": "i18n"."title_appbar": "i18n"."content": {
"currentLanguage": "The current language is English"."zh": "zh"."en": "en"}}Copy the code
- zh.json
{
"title_page": "Internationalization examples"."title_appbar": "Internationalization examples"."content": {
"currentLanguage": "Current language is Chinese"."zh": "Chinese"."en": "English"}}Copy the code
Create a new lang in lib
lang
|- config.dart
|- index.dart
Copy the code
- config.dart
import 'package:flutter/material.dart';
class ConfigLanguage {
static List<Locale> supportedLocales = [
Locale('zh'.'CH'),
Locale('en'.'US')];static Map<String.dynamic> supportLanguage = {
"zh": {"code": "zh"."country_code": "CH"},
"en": {"code": "en"."country_code": "US"}};static dynamic defaultLanguage = {
"code": "zh"."country_code": "CH"
};
}
Copy the code
The config.dart function consolidates configuration information into a file
- index.dart
import 'package:flutter/material.dart';
import 'dart:convert';
import 'package:flutter/services.dart' show rootBundle;
import 'package:flutter/foundation.dart' show SynchronousFuture;
import 'package:flutter_intl/lang/config.dart' as I18NConfig;
class AppLocalizations {
Locale _locale;
static Map<String.dynamic> jsonLanguage; / / language pack
static AppLocalizations _inst; // inst
AppLocalizations(this._locale);
// Initialize localizations
static Future<AppLocalizations> init(Locale locale) async {
_inst = AppLocalizations(locale);
await getLanguageJson();
return _inst;
}
// Get the language package
static Future getLanguageJson() async {
Locale _tmpLocale = _inst._locale;
print('Get the language pack's language;${_tmpLocale.languageCode}');
String jsonLang;
try {
jsonLang = await rootBundle.loadString('locale/${_tmpLocale.languageCode}.json');
} catch (e) {
print('Wrong');
_inst._locale = Locale(I18NConfig.ConfigLanguage.defaultLanguage['code']);
jsonLang = await rootBundle.loadString('locale/${I18NConfig.ConfigLanguage.defaultLanguage['code']}.json');
}
jsonLanguage = json.decode(jsonLang);
print("Current language:${_inst._locale}");
print(Data: $jsonLanguage);
}
// $t package, the purpose is to use $t to get multilingual data
static String $t(String key) {
var _array = key.split('. ');
var _dict = jsonLanguage;
var retValue = ' ';
try {
_array.forEach((item) {
if(_dict[item].runtimeType == Null) {
retValue = key;
return;
}
if(_dict[item].runtimeType ! =String) {
_dict = _dict[item];
} else{ retValue = _dict[item]; }}); retValue = retValue.isEmpty ? _dict : retValue; }catch (e) {
print('i18n exception');
print(e);
retValue = key;
}
return retValue ?? ' '; }}// Implement the LocalizationsDelegate protocol to initialize the Localizations class
class AppLocalizationsDelegate extends LocalizationsDelegate<AppLocalizations> {
final Locale locale;
AppLocalizationsDelegate([this.locale]);
@override
bool isSupported(Locale locale) {
return I18NConfig.ConfigLanguage.supportLanguage.keys
.toList()
.contains(locale.languageCode);
}
// Initialize Localizations class here
@override
Future<AppLocalizations> load(Locale _locale) async {
print('Language to load: $_locale');
return await AppLocalizations.init(_locale);
// return SynchronousFuture<AppLocalizations>(
// AppLocalizations(_locale)
// );
}
@override
bool shouldReload(LocalizationsDelegate<AppLocalizations> old) {
// Flase does not execute the above rewrite function
return false; }}Copy the code
See the code comment ~~~~~~~~~ for details
Just to give you an overview
Implement a LocalizationsDelegate protocol and implement a Localizations class and import it into the MaterialApp in Main. dart
Process the main.dart file
import 'package:flutter/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:flutter_intl/lang/index.dart'
show AppLocalizations, AppLocalizationsDelegate;
import 'package:flutter_intl/lang/config.dart' show ConfigLanguage;
void main () => runApp(MainApp());
GlobalKey<_ChangeLocalizationsState> changeLocalizationsStateKey = new GlobalKey<_ChangeLocalizationsState>();
class MainApp extends StatefulWidget {
@override
_MainAppState createState() => _MainAppState();
}
class _MainAppState extends State<MainApp> {
// Define the global language proxy
AppLocalizationsDelegate _delegate;
@override
void initState() {
// TODO: implement initState
_delegate = AppLocalizationsDelegate();
super.initState();
}
@override
Widget build(BuildContext context) {
return MaterialApp(
// locale: Locale('zh', 'CH'),
localeResolutionCallback: (deviceLocale, supportedLocal) {
print('deviceLocale: $deviceLocale, supportedLocale: $supportedLocal}');
// Determine whether the incoming language supports it
Locale _locale = supportedLocal.contains(deviceLocale) ? deviceLocale : Locale('zh'.'CN');
return _locale;
},
onGenerateTitle: (context) {
// Set up the multilingual proxy
// AppLocalizations.setProxy(setState, _delegate);
return AppLocalizations.$t('title_page');
},
// localizationsDelegates the element in the list is the factory that generates the localized collection
localizationsDelegates: [
GlobalMaterialLocalizations.delegate, // Provide localized strings and other values for the Material Components library
GlobalWidgetsLocalizations.delegate, // Define the default text orientation for the widget, from left to right or right to left
_delegate
],
supportedLocales: ConfigLanguage.supportedLocales,
initialRoute: '/',
routes: {
'/': (context) =>
// Home()
Builder(builder: (context) {
returnChangeLocalizations( key: changeLocalizationsStateKey, child: Home() ); })}); }}class Home extends StatelessWidget {
@override
Widget build(BuildContext context) {
Locale locale = Localizations.localeOf(context);
return Scaffold(
appBar: AppBar(title: Text('${AppLocalizations.$t('title_appbar')}'),),
body: ListView(
children: <Widget>[
Container(
margin: EdgeInsets.only(top: 60),
alignment: Alignment.center,
child: Text('${locale.languageCode} ${locale.toString()}'),
),
Container(
alignment: Alignment.center,
child: Text('${AppLocalizations.$t('content.currentLanguage')}'),
),
Wrap(
spacing: 8.0,
alignment: WrapAlignment.center,
children: <Widget>[
ActionChip(
backgroundColor: Theme.of(context).primaryColor,
onPressed: () {
changeLocalizationsStateKey.currentState.changeLocale(Locale('en'.'US'));
},
label: Text('${AppLocalizations.$t('content.en')}'),
),
ActionChip(
backgroundColor: Theme.of(context).primaryColor,
onPressed: () {
changeLocalizationsStateKey.currentState.changeLocale(Locale('zh'.'CH'));
},
label: Text('${AppLocalizations.$t('content.zh')}'() [() [() [() }}class ChangeLocalizations extends StatefulWidget {
final Widget child;
ChangeLocalizations({Key key, this.child}):super(key: key);
@override
_ChangeLocalizationsState createState() => _ChangeLocalizationsState();
}
class _ChangeLocalizationsState extends State<ChangeLocalizations> {
Locale _locale;
@override
void initState() {
super.initState();
}
@override
void didChangeDependencies() async {
super.didChangeDependencies();
// Get the language of the current device
_locale = Localizations.localeOf(context);
print('Device language: $_locale');
}
changeLocale(Locale locale) {
setState(() {
_locale = locale;
});
}
@override
Widget build(BuildContext context) {
returnLocalizations.override( context: context, locale: _locale, child: widget.child, ); }}Copy the code
- Specify the localizationsDelegate and supportedLocales in the MaterialApp
- LocaleResolutionCallback: This callback is used when the application retrieves the Locale set by the user. You can return the Locale as required
- OnGenerateTitle: Returns the corresponding title of the multilingual application
- LocalizationsDelegates: The factory where localization sets are generated when the elements in the localizationsDelegates list
- SupportedLocales: language supported by the APP
- The Home class is the display class
- Localizations. LocaleOf (context). LanguageCode obtains the language type of the current app
- AppLocalizations.$t(‘content.currentLanguage’) play with multilingual content like the Web
At this point, you can happily play with multiple languages, and different language packs will be loaded when the user sets different languages
The following implementation in the APP language switch
- The ChangeLocalizations class uses the Override method of Localizations, as shown above
- Internal method of calling ChangeLocalizations using GlobalKey, GlobalKey<_ChangeLocalizationsState> changeLocalizationsStateKey = new GlobalKey<_ChangeLocalizationsState>(); We can also be GlobalKey into dojo.provide, so that you can implement multiple pages for changeLocalizationsStateKey visit
- Modify language call changeLocale method, changeLocalizationsStateKey. CurrentState. ChangeLocale (Locale (‘ en ‘, ‘US’));
The last
Welcome more friends learning about flutter to join QQ group Flutter UI: 798874340
Stay tuned for what we’re working on: efoxTeam/ Futter-UI
The author