Flutter 中的国际化之多语言环境
程序员文章站
2022-05-29 10:54:12
...
本文章将综述:
- flutter 应用通过 MaterialApp 设置言本地化
- flutter 应用通过 MaterialApp 配制多语言国际化支持
本文章的终极效果:
通常我们新建的 Flutter 应用是默认不支持多语言的,即使用户在中文环境下,显示的文字仍然是英文,接下来我们将一步步将系统的这些组件国际化。
1 添加依赖
dependencies:
flutter:
sdk: flutter
flutter_localizations:
sdk: flutter
然后 运行
flutter packages get
以获取依赖
2 在 main.dart 中 import
import 'package:flutter_localizations/flutter_localizations.dart';
3 配置
在 MaterialApp 中配制
import 'package:flutter/material.dart';
import 'package:flutter_mo_study_ui/select_language_page.dart';
import 'package:flutter/foundation.dart';
import 'localizations_delegates.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
void main() => runApp(MyAppThem2());
///创建key值,就是为了调用外部方法
///ChangeLocalizationsState 用来应用内切换语言环境的类
GlobalKey<ChangeLocalizationsState> changeLocalizationStateKey = new GlobalKey<ChangeLocalizationsState>();
class MyAppThem2 extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
///android 应用任务栏显示的标题
// title: 'Flutter MU KE DEMO',
home: new Builder(builder: (context) {
///通过 Localizations.override 包裹一层。---这里
///将 ChangeLocalizations 使用到 MaterialApp 中
return new ChangeLocalizations(
key: changeLocalizationStateKey,
child: new SelectLanguagePage(),
);
}),
/// 此处 配制多语言环境
///配置 android 应用任务栏显示的标题 的国际化
///因为 DemoLocalizations 使用到了context 所以这里不使用title 属性
onGenerateTitle: (context) {
///根据语言环境来获取 taskTitle
///DemoLocalizations 为自定义的语言文字适配中心
return DemoLocalizations.of(context).taskTitle;
},
///本地化委托,用于更改Flutter Widget默认的提示语,按钮text等
///通常我们新建的 Flutter 应用是默认不支持多语言的,即使用户在中文环境下,显示的文字仍然是英文
localizationsDelegates: [
///初始化默认的 Material 组件本地化
GlobalMaterialLocalizations.delegate,
///初始化默认的 通用 Widget 组件本地化
GlobalWidgetsLocalizations.delegate,
///初始化自定义多语言环境运行
MyLocalizationsDelegates.delegate,
],
///当前区域,如果为null则使用系统区域一般用于语言切换
///传入两个参数,语言代码,国家代码
///这里配制为中国
locale: Locale('zh', 'CN'),
///传入支持的语种数组
supportedLocales: [
const Locale('en', 'US'), // English 英文
const Locale('he', 'IL'), // Hebrew 西班牙
const Locale('zh', 'CN'), // 中文,后面的countryCode暂时不指定
],
///当传入的是不支持的语种,可以根据这个回调,返回相近,并且支持的语种
localeResolutionCallback: (local, support) {
///当前软件支行的语言 也就是[supportedLocales] 中配制的语种
if (support.contains(local)) {
print('support $local');
return local;
}
///如果当前软件运行的手机环境不在 [supportedLocales] 中配制的语种范围内
///返回一种默认的语言环境,这里使用的是中文
print('no_support local is $local and support is $support');
return const Locale('zh', 'CN');
},
);
}
}
//自定义类 用来应用内切换
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 = const Locale('zh', 'CH');
changeLocale(Locale locale) {
setState(() {
_locale = locale;
});
}
//通过Localizations.override 包裹我们需要构建的页面
@override
Widget build(BuildContext context) {
//通过Localizations 实现实时多语言切换
//通过 Localizations.override 包裹一层。---这里
return new Localizations.override(
context: context,
locale: _locale,
child: widget.child,
);
}
}
对于类 MyLocalizationsDelegates
import 'dart:ui';
import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
///自定义多语言处理代理
class MyLocalizationsDelegates
extends LocalizationsDelegate<DemoLocalizations> {
///构造
const MyLocalizationsDelegates();
///静态构造
static MyLocalizationsDelegates delegate = const MyLocalizationsDelegates();
@override
bool isSupported(Locale locale) {
return ['en', 'zh', 'he'].contains(locale.languageCode);
}
@override //是否需要重载
bool shouldReload(LocalizationsDelegate old) => false;
///MyLocalizations就是在此方法内被初始化的
///通过方法的 locale 参数,判断需要加载的语言,然后返回自定义好多语言实现类MyLocalizations
///最后通过静态 delegate 对外提供 LocalizationsDelegate。
@override
Future<DemoLocalizations> load(Locale locale) {
//加载本地化
return new SynchronousFuture(new DemoLocalizations(locale));
}
}
对于 DemoLocalizations 是配置 具体的文字内容
///Localizations类 用于语言资源整合
class DemoLocalizations {
///该Locale类是用来识别用户的语言环境
/// 在MyLocalizationsDelegates 的load方法中初始化的
final Locale locale;
DemoLocalizations(this.locale);
///此处通过静态方式来初始化
static DemoLocalizations of(BuildContext context) {
///Localizations 是多国语言资源的汇总
return Localizations.of(context, DemoLocalizations);
}
//根据不同locale.languageCode 加载不同语言对应
static Map<String, Map<String, String>> _localizedValues = {
'en': {
'task title': 'Flutter Demo',
'titlebar title': 'Flutter Demo Home Page',
'click tip': 'You have pushed the button this many times:',
'inc': 'Increment',
'click button': 'click select language',
'welcomes': 'China welcomes you'
},
'zh': {
'task title': 'Flutter 示例',
'titlebar title': 'Flutter 示例主页面',
'click tip': '你一共点击了这么多次按钮:',
'inc': '增加',
'click button': '点击切换',
'welcomes': '中国欢迎你'
},
'he': {
'task title': 'Ejemplo de Flutter',
'titlebar title': 'Flutter 示例主页面',
'click tip': 'Has hecho clic en los botones tantas veces en total:',
'inc': '增加',
'click button': 'Haga clic en cambiar',
'welcomes': 'Bienvenido a China'
}
};
get taskTitle {
Map<String, String> map = _localizedValues[locale.languageCode];
return map['task title'];
}
get titleBarTitle {
return _localizedValues[locale.languageCode]['titlebar title'];
}
get clickButtonTitle {
return _localizedValues[locale.languageCode]['click button'];
}
get clickTop {
return _localizedValues[locale.languageCode]['click tip'];
}
get inc {
return _localizedValues[locale.languageCode]['inc'];
}
get welcomes {
return _localizedValues[locale.languageCode]['welcomes'];
}
}
SelectLanguagePage 页面中 点击按钮实现应用内切换当前语言环境
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_mo_study_ui/localizations_delegates.dart';
import 'package:flutter_mo_study_ui/second_page.dart';
import 'main_language.dart';
/**
* 多语言切换
*/
class SelectLanguagePage extends StatefulWidget {
SelectLanguagePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<SelectLanguagePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
///多种语言支持的导航栏标题
title: Text(DemoLocalizations.of(context).titleBarTitle),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
///多种语言支持的显示文本
Text(DemoLocalizations.of(context).welcomes,style: TextStyle(color: Colors.red,fontSize: 22),),
Padding(
padding: EdgeInsets.all(30),
),
///点击按钮显示语言选择框
FlatButton(
child: Text(DemoLocalizations.of(context).clickButtonTitle),
onPressed: () {
changeLocale();
},
)
],
),
),
);
}
///语言切换
///这里则是弹框内容了
void changeLocale(){
showDialog(
context: context,
barrierDismissible: false,//// user must tap button!
builder: (BuildContext context) {
return new SimpleDialog(
title: new Text("请选择语言"),
children: <Widget>[
SimpleDialogOption(
onPressed: () {
switchLanguage(0);
Navigator.of(context).pop();
},
child: const Text("中文"),
),
SimpleDialogOption(
onPressed: () {
switchLanguage(1);
Navigator.of(context).pop();
},
child: const Text("英语"),
),
SimpleDialogOption(
onPressed: () {
switchLanguage(2);
Navigator.of(context).pop();
},
child: const Text("西班牙语"),
)
],
);
},
);
}
///切换语言
///通过 changeLocalizationStateKey 来修改本应用内的 Locale
void switchLanguage(int index) {
switch(index){
case 0:
changeLocalizationStateKey.currentState.changeLocale(const Locale('zh','CH'));
break;
case 1:
changeLocalizationStateKey.currentState.changeLocale(const Locale('en','US'));
break;
case 2:
changeLocalizationStateKey.currentState.changeLocale(const Locale('he', 'IL'));
break;
}
}
}