English
简体中文
对于现在的APP应用,国际化需求并不高,但是作为一项有用的功能,我们还是按部就班地去实现它,由于还未完成全局状态管理和全局事件总线,暂时使用了一个全局变量Locale去定义,因此要完成切换就需要手动修改变量值后重启应用(热更新是不可以的),目前仅实现简体中文和美式英文两种语言
1.引入国际化需要的包。
2.在Flutter节点下添加generate,可以在重启或者热更新时实时更新翻译文件。
3.在根目录下增加l10n.yaml文件,用于配置实时更新的内容。
dependencies:
#语言国际化
flutter_localizations: #必须有
sdk: flutter
flutter_localized_locales: ^2.0.3 #可以从 563 语言环境的语言环境代码(ISO 639‑2 和 ISO 639-3)中获取本地化语言环境名称。
intl: ^0.17.0
flutter:
#国际化
generate: true # 添加这一行
#以下是l10n.yaml文件的内容
arb-dir: lib/l10n #翻译文件所在的目录
template-arb-file: app_zh.arb #模板文件
output-localization-file: app_localizations.dart #输出的资源文件
4.在根Widget的MaterialApp中增加如下配置,大多都是来自第三步自动更新的内容,如果编译器不能自动识别,可以手动引入如下包:import 'package:flutter_gen/gen_l10n/app_localizations.dart';
MaterialApp(
onGenerateTitle: (context) => AppLocalizations.of(context)!.app,//title实现国际化的方式
locale: locale,
localizationsDelegates: const [
LocaleNamesLocalizationsDelegate(),
AppLocalizations.delegate,
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
FallbackCupertinoLocalisationsDelegate(),
GlobalCupertinoLocalizations.delegate,
],
supportedLocales: AppLocalizations.supportedLocales,
localeResolutionCallback:
(Locale? _locale, Iterable? supportedLocales) {
/// [supportedLocales] : supportedLocales
///iOS上语言表示不一样 [en_US, zh_CN] zh_Hans_CN languageCode-scriptCode-countryCode
///这个判断会使手机端访问出问题 zh_cn 而不是Zh_CN
debugPrint(_locale.toString());
Locale locale = const Locale.fromSubtags(
languageCode: 'zh'); //当APP不支持系统设置的语言时,设置默认语言
/// [todo]遍历系统选择的语言是否是支持的语言,去除了脚本代码,暂时没测会不会有问题,ios系统带了脚本代码
supportedLocales?.forEach((l) {
if ((l.countryCode == _locale?.countryCode) &&
(l.languageCode == _locale?.languageCode)) {
locale = Locale.fromSubtags(
languageCode: l.languageCode,
scriptCode: l.scriptCode,
countryCode: l.countryCode);
}
});
return locale;
},
......
)
5.编译翻译文件,在lib/I10n的目录下新增app_zh.arb和app_en.arb两个文件(如果要具体到国家代码可以新建为app_zh_CN.arb和app_en_US.arb),文件采用Json的语法,Vscode等编辑器也有对应的语法插件,至于翻译语法,大家可以自行了解,限于篇幅,仅做常用的展示。
{
"app": "猫猫侠的正义",
"@app": {
"description": "对app的描述"
},
"hit6": "{howMany,plural, other{倒计时{howMany}s}}",
"@hit6": {
"type": "text",
"placeholders": {
"howMany": {
"example": "42"
}
}
},
}
注:app表示变量名,后续可以使用AppLocalizations.of(context)!.app调用,语言切换时就会按照对应的翻译文件进行展示。
@app表示对app变量的描述,是给翻译人员看的,与代码运行无关。
模板语句,有时候需要实现类似“倒计时20秒”只有数字变化的语句,此时就形成了模板插值语句,在模板上插入数字,上述hit6即实现了这样一个语法,最终会被翻译为一个函数,读者可自行尝试。
关于iOS平台
尝试过国际化的读者可能发现在iOS平台无法顺利完成切换(上述全局变量方式和使用全局状态管理的实现方式有本质区别,注意区分),这是因为iOS应用程序有一套自建的语言环境管理机制,所以使用上面的方式适配国际化对于iOS应用程序是无效的,为了让iOS应用程序也能支持国际化,还需要在原生iOS工程中进行额外的配置。 使用Xcode打开Flutter项目的iOS原生工程,切换到工程面板,然后在Localization选项配置中添加中文支持即可。
在Android/ios平台权限处理是绕不开的内容,本应用作为demo应用,会尽可能地多索要权限,但是设计为仅在用户安装后第一次打开时索取一次,后续不再主动索取,仅在用户需要使用相关功能时引导用户给予权限即可。权限管理的实现相对简单,可以引用permission_handler包,并加入以下代码,在APP启动时调用一次requestAllPermission函数即可。
///需要的权限
const _permission = [
Permission.camera,
Permission.location,
// Permission.locationAlways,
Permission.locationWhenInUse,
Permission.mediaLibrary, //如果不在info.plist中声明,会直接崩溃
Permission.microphone,
Permission.photos,
Permission.storage,
Permission.notification,
];
/// 用来第一次安装app时获取全部权限
Future requestAllPermission() async {
int i = 0;
Map permissions =
await PermissionListActions(_permission).request();
permissions.forEach((key, value) {
if (value != PermissionStatus.granted) {
i++;
}
});
return i;
}
值得注意的是Android/iOS平台都有属于自己的权限清单文件AndroidManifest.xml/info.plist,在Flutter中索取的权限一定要预先在对应平台清单文件中声明,否则会权限索要失败以及应用闪退。
下章内容:主题切换,欢迎页,引导页,
关注后私信对应编号(20211111)获取对应的源码和素材
小破站同名,同步文章且定时直播编程,有兴趣可以移步
加关注不迷路,评论私信会不定时回复,欢迎一起讨论
投稿时间:2021-11-12 最后更新:2022-06-23
本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828
© CopyRight 2008-2022 All Rights Reserved. Powered By Q578.com 闽ICP备11008920号-1
闽公网安备35020302032606号