原创文章:转载请注明出处
项目地址:
https://github.com/bettersun/helloflutterintl.git
APP内可实时切换语言,同时保存切换后语言。
默认启动是简体中文,下次启动为保存后的语言。
该APP设置了四种语言: 简体中文、繁体中文、英语、日语。
先上图
简体中文
繁体中文
英语
日语
1. 添加依赖
pubspec.yaml
# 国际化
flutter_localizations:
sdk: flutter
flutter_cupertino_localizations:
intl:
intl_translation:
# 本地存储
shared_preferences:
2. 手动添加多语言类并生成多语言文件
手动添加多语言类 message.dart
参照链接(该链接内容很详细):
https://www.jianshu.com/p/82c6656462b8
3. 基于message.dart生成arb文件
flutter pub pub run intl_translation:extract_to_arb --output-dir=lib/localization lib/localization/message.dart
4. 生成多语言dart文件
生成的arb文件重命名为各语言对应arb(例:message_zh_CN.arb)
然后执行命令生成对应的dart文件
例:
简体中文:
flutter pub pub run intl_translation:generate_from_arb --output-dir=lib/localization --no-use-deferred-loading lib/localization/message.dart lib/localization/message_zh_CN.arb
英文:
flutter pub pub run intl_translation:generate_from_arb --output-dir=lib/localization --no-use-deferred-loading lib/localization/message.dart lib/localization/message_en.arb
5. 定义全局语言切换Controller(locale_controller.dart)
import 'package:flutter/material.dart';
typedef ChangeLocaleCallback = void Function(Locale locale);
/// 多语言切换
class LocaleController {
/// 语言切换回调方法
ChangeLocaleCallback onLocaleChanged;
/// Internals
static final LocaleController _localeController = LocaleController._internal();
factory LocaleController() {
return _localeController;
}
LocaleController._internal();
}
/// 语言切换控制器实例
LocaleController localeController = LocaleController();
6. 定义多语言委托(locale_delegate.dart)
BsMessageLocalDelegate
BsCupertinoLocalDelegate
BsMaterialLocalizationsDelegate
7. main方法中读取本地存储里的Locale,并设置给启动APP
取不到默认使用简体中文
void main() async {
WidgetsFlutterBinding.ensureInitialized();
final SharedPreferences preferences = await SharedPreferences.getInstance();
// 从本地存储中取得已保存的语言
String localeName = preferences.getString(PreferenceKey.localeName);
// 取不到默认设置为简体中文
localeName = localeName ?? LocaleConst.zhCN.toString();
// 启动程序
runApp(BsApp(localeName: localeName));
}
8. 启动App里初始化多语言委托,并绑定全局事件用来更改App的State
class _BsAppState extends State<BsApp> {
// 语言委托
// App用
BsMessageLocalDelegate _bsMessageLocalDelegate;
// iOS用
BsCupertinoLocalDelegate _bsCupertinoLocalDelegate;
// 系统共通用(复制、粘贴等)
BsMaterialLocalizationsDelegate _bsMaterialLocalizationsDelegate;
@override
void initState() {
super.initState();
final Locale locale = toLocale(widget.localeName);
// 语言委托初始化
_bsMessageLocalDelegate = BsMessageLocalDelegate(locale);
_bsCupertinoLocalDelegate = BsCupertinoLocalDelegate(locale);
_bsMaterialLocalizationsDelegate = BsMaterialLocalizationsDelegate(locale);
// 语言切换回调方法
// 绑定全局事件用来更改App的State
localeController.onLocaleChanged = onLocaleChange;
}
/// 语言地区字符串转语言地区
Locale toLocale(String localName) {
assert(localName != null);
final List<String> localeCode = localName.split('_');
if (localeCode.length > 1) {
return Locale(localeCode[0], localeCode[1]);
} else if (localeCode.isNotEmpty) {
return Locale(localeCode[0]);
}
}
/// 语言切换
void onLocaleChange(Locale newLocale) {
setState(() {
_bsMessageLocalDelegate = BsMessageLocalDelegate(newLocale);
_bsCupertinoLocalDelegate = BsCupertinoLocalDelegate(newLocale);
_bsMaterialLocalizationsDelegate = BsMaterialLocalizationsDelegate(newLocale);
});
}
@override
Widget build(BuildContext context) {
return MaterialApp(
title: ' ', // 这个地方多语言Message还未加载,无法使用Message响应多语言
theme: ThemeData(
primarySwatch: Colors.blue,
),
// 语言委托
localizationsDelegates: [
_bsMessageLocalDelegate,
_bsCupertinoLocalDelegate,
_bsMaterialLocalizationsDelegate,
GlobalWidgetsLocalizations.delegate,
],
// 支持的语言
supportedLocales: const <Locale>[
LocaleConst.zhCN,
LocaleConst.zhHK,
LocaleConst.en,
LocaleConst.en,
],
home: const BsHome(),
);
}
}
9. 切换语言事件里调用全局事件触发启动App里的setState来实时改变App语言,并保存切换后语言
/// 切换语言
Future<void> _changeLocale() async {
_localeIndex++;
Locale locale = LocaleConst.zhCN;
// 切换语言
if (_localeIndex % _localeTotal == 0) {
locale = LocaleConst.zhCN;
}
if (_localeIndex % _localeTotal == 1) {
locale = LocaleConst.zhHK;
}
if (_localeIndex % _localeTotal == 2) {
locale = LocaleConst.en;
}
if (_localeIndex % _localeTotal == 3) {
locale = LocaleConst.ja;
}
// 切换语言
// 调用全局事件触发启动App里的setState
localeController.onLocaleChanged(locale);
final SharedPreferences preferences = await SharedPreferences.getInstance();
// 切换后的语言保存到本地存储
preferences.setString(PreferenceKey.localeName, locale.toString());
}