介绍
多语言方案:flutter_localizations 与 GetX 配合版,好处:命令行生成多语言字符串的引用常量类,缺点:切换语言以后,主界面需要手动触发setState,重绘将最新的Locale数据设置给GetMaterialApp。
目录
- 介绍
- 运行效果
- 一、安装
- 二、使用
- 1.lib文件夹中新建文件夹l10n/arb,并在其中创建app_en.arb 、app_zh.arb、app_zh_HK.arb文件
- 2.项目的根目录中添加l10n.yaml,配置如下
- 3.添加完成之后,执行命令`flutter gen-l10n`,执行命令`flutter run`,.dart_tools会自动生成相关的文件
- 4.MaterialApp改成GetMaterialApp配置国际化字段
- 5.调用
- 6.多语言切换
运行效果
一、安装
dependencies:
flutter_localizations:
sdk: flutter
intl: any
get: ^4.6.6
flutter:
uses-material-design: true
generate: true
二、使用
1.lib文件夹中新建文件夹l10n/arb,并在其中创建app_en.arb 、app_zh.arb、app_zh_HK.arb文件
app_en.arb类
{
"@@locale": "en",
"appName": "BraveComponent",
"@appName": {
"description": "备注"
},
"helloWorld": "HelloWorld",
"followerSystemLanguage": "FollowerSystemLanguage",
"simplifiedChinese": "SimplifiedChinese",
"traditionalChinese": "TraditionalChinese",
"english": "English",
"setting": "Setting",
"multiLanguage": "MultiLanguage",
"theme": "Theme"
}
app_zh.arb类
{
"@@locale": "zh",
"appName": "BraveComponent",
"@appName": {
"description": "备注"
},
"helloWorld": "你好,世界",
"followerSystemLanguage": "跟随系统语言",
"simplifiedChinese": "简体中文",
"traditionalChinese": "繁体中文",
"english": "英文",
"setting": "设置",
"multiLanguage": "多语言",
"theme": "主题"
}
app_zh.arb类
{
"@@locale": "zh_HK",
"appName": "BraveComponent",
"@appName": {
"description": "備注"
},
"helloWorld": "妳好,世界",
"followerSystemLanguage": "跟隨系統語言",
"simplifiedChinese": "簡體中文",
"traditionalChinese": "繁體中文",
"english": "英文",
"setting": "設置",
"multiLanguage": "多語言",
"theme": "主題"
}
2.项目的根目录中添加l10n.yaml,配置如下
arb-dir: lib/l10n/arb
template-arb-file: app_zh.arb
output-localization-file: app_localizations.dart
output-class: AppLocalizations
use-deferred-loading: true
nullable-getter: false
3.添加完成之后,执行命令flutter gen-l10n
,执行命令flutter run
,.dart_tools会自动生成相关的文件
4.MaterialApp改成GetMaterialApp配置国际化字段
l10n_app.dart类代码
import 'package:brave_component/core/utils/language_utils.dart';
import 'package:flutter/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:get/get.dart';
import 'l10n/l10n.dart';
import 'routes/route_pages.dart';
import 'routes/route_path.dart';
class L10nApp extends StatefulWidget {
bool _init = true;
L10nApp({super.key});
@override
State<L10nApp> createState() => L10nAppState();
}
class L10nAppState extends State<L10nApp> {
// 供外部使用的_AppSetting实例,用于修改app的状态
static AppSetting setting = AppSetting.instance;
@override
void initState() {
super.initState();
//第一次进入app时,获取本地多语言的countryCode
if (widget._init) {
setting.setLocale();
widget._init = false;
}
// 更改语言
setting.changeLocale = () {
setState(() {});
};
}
@override
Widget build(BuildContext context) {
return GetMaterialApp(
initialRoute: RoutePath.l10n_main,
getPages: RoutePages.getPages,
title: 'component',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
locale: setting._locale,
fallbackLocale: const Locale("zh", "CN"),
localeResolutionCallback: (deviceLocale, supportedLocales) {
print('当前语言:${deviceLocale.toString()}');
return;
},
supportedLocales: AppLocalizations.supportedLocales,
localizationsDelegates: const [
AppLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
GlobalMaterialLocalizations.delegate
],
);
}
}
class AppSetting {
AppSetting._();
static final AppSetting _instance = AppSetting._();
static AppSetting get instance => _instance;
Locale? _locale;
Function()? changeLocale;
void setLocale() {
_locale = LanguageUtils.getLocale();
}
}
language_utils.dart类代码
import 'package:brave_component/l10n/l10n.dart';
import 'package:flutter/widgets.dart';
import 'package:get/get.dart';
import '../../l10n_app.dart';
import '../cache/helpers/cache_helper.dart';
import '../enums/language.dart';
class LanguageUtils {
static String getLanguage(BuildContext context, String code) {
late String language;
switch (code) {
case 'fs-Lan':
language = context.l10n.followerSystemLanguage;
break;
case 'zh-CN':
language = context.l10n.simplifiedChinese;
break;
case 'zh-HK':
language = context.l10n.traditionalChinese;
break;
case 'en-US':
language = context.l10n.english;
break;
default:
language = context.l10n.followerSystemLanguage;
break;
}
return language;
}
static Locale? getLocale() {
Locale? locale;
String code = CacheHelper.countryCode;
List<String> lang = code.split('-');
locale = (code == Language.fsLan.countryCode)
? Get.deviceLocale
: Locale(lang[0], lang[1]);
return locale;
}
static void updateLocale(String countryCode, {bool isL10n = false}) {
List<String> lang = countryCode.split('-');
Get.updateLocale((countryCode == Language.fsLan.countryCode)
? Get.deviceLocale!
: Locale(lang[0], lang[1]));
CacheHelper.saveCountryCode(countryCode);
if (isL10n) {
L10nAppState.setting.changeLocale!();
}
}
}
mian.dart类
import 'package:flutter/material.dart';
import 'app.dart';
import 'core/cache/cache/cache.dart';
import 'l10n_app.dart';
void main() async {
await Cache.instance.init();
runApp(L10nApp()); //flutter_localizations与GetX配合版的多语言
// runApp(const App()); //GetX版多语言
}
5.调用
- 直接使用 Text(AppLocalizations.of(context).helloWorld)
- 扩展使用
- 扩展BuildContext
extension BuildContextExtension on BuildContext {
AppLocalizations get l10n => AppLocalizations.of(this);
}
- 使用
Text(context.l10n.helloWorld)
6.多语言切换
l10n_multi_language_view.dart类
import 'package:brave_component/core/enums/language.dart';
import 'package:brave_component/l10n/l10n.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import '../../../../../core/res/colours.dart';
import '../../../../../widgets/base/texts.dart';
import 'l10n_multi_language_logic.dart';
class L10nMultiLanguagePage extends StatelessWidget {
L10nMultiLanguagePage({super.key});
final logic = Get.find<L10nMultiLanguageLogic>();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Texts.fontSize18Normal(context.l10n.multiLanguage,
color: Colours.titleColor),
leading: GestureDetector(
onTap: () {
Get.back(result: 'changeLanguage');
},
child: const Icon(Icons.arrow_back),
),
),
body: Container(
padding: const EdgeInsets.symmetric(vertical: 15),
// child: ListView(
// children: ListTile.divideTiles(
// context: context,
// tiles: Language.values
// .map((e) =>
// GetBuilder<MultiLanguageLogic>(builder: (logic) {
// return ListTile(
// title: Texts.fontSize14Normal(e.title,
// color: Colours.titleColor),
// trailing: e.countryCode == logic.countryCode
// ? const Icon(Icons.check,
// color: Colours.primaryColor)
// : null,
// onTap: () {
// logic.changeLanguage(e.countryCode);
// },
// );
// }))
// .toList())
// .toList(),
// ),
child: ListView.separated(
itemBuilder: (context, index) {
return _itemContent(context, index);
},
separatorBuilder: (_, index) => const Divider(),
itemCount: Language.values.length),
),
);
}
Widget _itemContent(BuildContext context, int index) {
return GetBuilder<L10nMultiLanguageLogic>(builder: (logic) {
return Container(
padding: const EdgeInsets.symmetric(horizontal: 15),
height: 44,
child: GestureDetector(
onTap: () {
logic.changeLanguage(Language.values[index].countryCode);
},
child: Row(
children: [
Expanded(
child: Texts.fontSize14Normal(Language.values[index].title,
color: Colours.titleColor)),
Visibility(
visible:
logic.countryCode == Language.values[index].countryCode,
child: const Icon(Icons.check, color: Colours.primaryColor))
],
),
),
);
});
}
}
l10n_multi_language_logic.dart类
import 'package:brave_component/core/cache/helpers/cache_helper.dart';
import 'package:brave_component/core/utils/language_utils.dart';
import 'package:get/get.dart';
class L10nMultiLanguageLogic extends GetxController {
late String countryCode;
@override
void onInit() {
super.onInit();
countryCode = CacheHelper.countryCode;
}
void changeLanguage(String code) {
countryCode = code;
LanguageUtils.updateLocale(code, isL10n: true);//切换Locale
update();
}
}
l10n_multi_language_binding.dart类
import 'package:get/get.dart';
import 'l10n_multi_language_logic.dart';
class L10nMultiLanguageBinding extends Bindings {
@override
void dependencies() {
Get.lazyPut(() => L10nMultiLanguageLogic());
}
}
language 类
enum Language {
fsLan(title: "跟随系统语言", countryCode: "fs-Lan"),
zhCN(title: "简体中文", countryCode: "zh-CN"),
zhHK(title: "繁体中文", countryCode: "zh-HK"),
enUS(title: "English", countryCode: "en-US");
final String title;
final String countryCode;
const Language({required this.title, required this.countryCode});
}
这里关于GetX的binding用法不会的可以参考Flutter GetX使用—简洁的魅力!这个博主开发的GetX插件,生成模版代码提高研发效率,建议看看用起来。
持久化就不赘述了,参考源码
源码
下一篇 多语言方案二:GetX 版