在說flutter國(guó)際化前检号,不得不提到蛙酪,在uni-app中支持的Vue-i18n齐苛,兩者有相似之處,也有差異的地方桂塞。
本篇借鑒了三篇熱門帖子
Flutter中的國(guó)際化:如何寫一個(gè)多語(yǔ)言的App
Flutter國(guó)際化完整例子
Internationalization - Make an Flutter application multi-lingual
只記錄根據(jù)手機(jī)系統(tǒng)語(yǔ)言自動(dòng)轉(zhuǎn)換app語(yǔ)言
1.引入依賴
引入后,保存會(huì)自動(dòng)加入安裝此依賴
//pubspec.yaml
dependencies:
flutter:
sdk: flutter
flutter_localizations: #多語(yǔ)言
sdk: flutter
//這里是Http網(wǎng)絡(luò)請(qǐng)求需要加入的
dio: ^2.1.13 #Http 請(qǐng)求Dio
http: ^0.12.0 #http
json_serializable: ^3.1.0 #json 序列化
json_annotation: ^2.4.0 #json 注釋
2.創(chuàng)建翻譯json文件和添加配置
我們新建一個(gè)和"/lib"同級(jí)別的文件夾"/locale"狂打,然后在這個(gè)文件夾中新建兩個(gè)文件擂煞,分別為"i18n_en.json" 和" i18n_zh.json"。再在"/lib"文件夾下創(chuàng)建和"main.dart"同級(jí)的"translation.dart"和"application.dart"趴乡。
??文件夾樹現(xiàn)在是這個(gè)樣子的:
MyApplication
? |
? +- android
? +- build
? +- images
? +- ios
? +- lib
?? |
?? +-main.dart
?? +-translation.dart
?? +-application.dart
? +- locale
?? |
?? +- i18n_en.json
?? +- i18n_zh.json
? +- test
//i18n_zh.json or i18n_en.json
{ "hello" : "你好对省!" , "hello" : "Hello~" }
在pubspec.yaml繼續(xù)加入json蝗拿,引入靜態(tài)資源
assets:
- locale/i18n_zh.json
- locale/i18n_en.json
//圖片也是需要手動(dòng)加入到assets中的
- images/lake.jpg
- images/number.png
3.main.dart中加入配置
//導(dǎo)入flutter的包
import 'package:flutter_localizations/flutter_localizations.dart';
import 'translation.dart';
import 'application.dart';
void main(){
debugPaintSizeEnabled = !true;
runApp(MyApp());
}
/// 將App設(shè)置為Stateful,這讓它可以響應(yīng)刷新事件蒿涎,調(diào)用應(yīng)用的SetState()
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => new _MyAppState();
}
class _MyAppState extends State<MyApp> {
SpecificLocalizationDelegate _localeOverrideDelegate;
@override
void initState(){
super.initState();
/// 初始化一個(gè)新的Localization Delegate蛹磺,有了它,當(dāng)用戶選擇一種新的工作語(yǔ)言時(shí)同仆,可以強(qiáng)制初始化一個(gè)新的Translations
_localeOverrideDelegate = new SpecificLocalizationDelegate(null);
/// 保存這個(gè)方法的指針萤捆,當(dāng)用戶改變語(yǔ)言時(shí),我們可以調(diào)用applic.onLocaleChanged(new Locale('en',''));俗批,通過SetState()我們可以強(qiáng)制App整個(gè)刷新
applic.onLocaleChanged = onLocaleChange;
}
/// 改變語(yǔ)言時(shí)的應(yīng)用刷新核心俗或,每次選擇一種新的語(yǔ)言時(shí),都會(huì)創(chuàng)造一個(gè)新的SpecificLocalizationDelegate實(shí)例岁忘,強(qiáng)制Translations類刷新辛慰。
onLocaleChange(Locale locale){
setState((){
_localeOverrideDelegate = new SpecificLocalizationDelegate(locale);
});
}
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
localizationsDelegates: [
_localeOverrideDelegate, // 注冊(cè)一個(gè)新的delegate
const TranslationsDelegate(), // 指向默認(rèn)的處理翻譯邏輯的庫(kù)
// 本地化的代理類
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
],
supportedLocales: applic.supportedLocales(),
title: 'Flutter Router',
debugShowCheckedModeBanner: false, //關(guān)掉模擬器右上角debug圖標(biāo)
theme: ThemeData(
primarySwatch: Colors.orange,
),
home: Homes(),
//路由表設(shè)置
routes: <String, WidgetBuilder>{
'/Second':(BuildContext context) => new SecondPage(),
'/Http':(BuildContext context) => new HttpPage(),
},
);
}
}
......
//Homes()省略了
4.給translation.dart和application.dart添加內(nèi)容
//application.dart
import 'package:flutter/material.dart';
typedef void LocaleChangeCallback(Locale locale);
class APPLIC {
// List of supported languages
final List<String> supportedLanguages = ['en','zh'];
// Returns the list of supported Locales
Iterable<Locale> supportedLocales() => supportedLanguages.map<Locale>((lang) => new Locale(lang, ''));
// Function to be invoked when changing the working language
LocaleChangeCallback onLocaleChanged;
///
/// Internals
///
static final APPLIC _applic = new APPLIC._internal();
factory APPLIC(){
return _applic;
}
APPLIC._internal();
}
APPLIC applic = new APPLIC();
//translation.dart
import 'dart:async';
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart' show rootBundle;
import 'application.dart';
class Translations {
Translations(Locale locale) {
this.locale = locale;
_localizedValues = null;
}
Locale locale;
static Map<dynamic, dynamic> _localizedValues;
static Translations of(BuildContext context){
return Localizations.of<Translations>(context, Translations);
}
String text(String key) {
try {
String value = _localizedValues[key];
if(value == null || value.isEmpty) {
return englishText(key);
} else {
return value;
}
} catch (e) {
return englishText(key);
}
}
String englishText(String key) {
return _localizedValues[key] ?? '** $key not found';
}
static Future<Translations> load(Locale locale) async {
Translations translations = new Translations(locale);
String jsonContent = await rootBundle.loadString("locale/i18n_${locale.languageCode}.json");
_localizedValues = json.decode(jsonContent);
return translations;
}
get currentLanguage => locale.languageCode;
}
class TranslationsDelegate extends LocalizationsDelegate<Translations> {
const TranslationsDelegate();
/// 改這里是為了不硬編碼支持的語(yǔ)言
@override
bool isSupported(Locale locale) => applic.supportedLanguages.contains(locale.languageCode);
@override
Future<Translations> load(Locale locale) => Translations.load(locale);
@override
bool shouldReload(TranslationsDelegate old) => false;
}
/// Delegate類的實(shí)現(xiàn),每次選擇一種新的語(yǔ)言時(shí)干像,強(qiáng)制初始化一個(gè)新的Translations類
class SpecificLocalizationDelegate extends LocalizationsDelegate<Translations> {
final Locale overriddenLocale;
const SpecificLocalizationDelegate(this.overriddenLocale);
@override
bool isSupported(Locale locale) => overriddenLocale != null;
@override
Future<Translations> load(Locale locale) => Translations.load(overriddenLocale);
@override
bool shouldReload(LocalizationsDelegate<Translations> old) => true;
}
5.獲取翻譯
......
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("JSON"),
),
body:Center(
child: Column(
children: <Widget>[
Text(Translations.of(context).text('hello')) //這里
],
)
),......
補(bǔ)充:如果需要強(qiáng)制轉(zhuǎn)換的話(小編自己沒有用到)
//為了強(qiáng)制切換另一種工作語(yǔ)言帅腌,只需要一行代碼,可以在App的任何地方調(diào)用:
applic.onLocaleChanged(new Locale('fr',''));