借助App Store与Google Play,全世界任何一个国家的使用者均可以使用咱们开发的应用,不过因为应用的使用者来自不一样国家,因此在应用正式上架以前须要让应用可以支持多种语言,即应用的国际化。
在Flutter开发中,应用的国际化主要涉及语言和地区差别性配置两个方面,它们是应用程序的组成部分之一。关于语言的国际化比较好理解,而地区差别性配置指的是根据国家风俗的不一样进行的差别性配置。按照Flutter官方的适配方案,要在Flutter应用中实现语言的国际化,须要通过如下几步。app
能够发现,若是直接按照官方提供的国际化方案来进行应用适配,不只工做量大并且极易出错。为了达到快速适配,减小代码编写形成的错误,可使用Android Studio提供的Flutter i18n国际化插件。若是尚未安装Flutter i18n插件,能够打开Android Studio,而后依次选择【Preference】→【Plugins】→【Marketplace】搜索Flutter i18n插件进行安装,以下图所示。less
安装完成以后,重启Android Studio就可使用它进行Flutter的国际化适配了。须要说明的是,因为最新版的Android Studio已经不支持使用应用市场的方式来安装Flutter i18n插件,因此须要先从Jetbrains官网下载后再从本地进行安装,以下图所示。ide
因为Flutter i18n插件须要依赖flutter_localizations插件包,因此执行国际化适配以前,还须要在pubspec.yaml文件中添加flutter_localizations依赖,以下所示。ui
dependencies: flutter_localizations: sdk: flutter
在命令行中使用flutter packages get命令拉取依赖。而后,在项目的根目录下会自动生成一个res文件夹,该文件夹默认会包含一个strings_en.arb文件,arb文件的格式以下。spa
{ "app_name": "Flutter App internationalization", "main_title": "Flutter i18n", "main_content" : "You have click the button many times" }
arb文件是JSON格式的配置文件,能够用来存放文案标识符和文案翻译的键值对。事实上,这种将字符串文本分离成单独文件的作法,能够方便开发人员和翻译人员分工协做,从而提升适配效率。
默认状况下,系统只会生成英文资源配置strings_en.arb文件,若是要支持中文,则须要使用手动的方式在values目录下增长一个strings_zh.arb文件。在res/values文件夹上右键,而后依次选择【New】→【Arb File】→【Choose language】建立一个名为strings_zh.arb的arb文件,并添加以下内容。插件
{ "app_name": "Flutter应用国际化", "main_title": "Flutter国际化", "main_content" : "点击按钮次数: $count" }
实际使用时,只须要修改res/values目录下的arb文件内容,i18n插件就会自动生成对应的Dart转换代码,以下图所示。
须要说明的是,因为i18n.dart文件的代码是由插件自动生成的,因此不要手动修改里面的内容。接下来,还须要在应用程序的入口,即MaterialApp中设置国际化所需的两个重要参数localizationsDelegates与supportedLocales,以下所示。命令行
class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( localizationsDelegates: const [ S.delegate, GlobalMaterialLocalizations.delegate, GlobalWidgetsLocalizations.delegate ], supportedLocales: S.delegate.supportedLocales, home: MyHomePage(title: '本地化'), ); } }
其中,localizationsDelegates表示应用程序的翻译回调,supportedLocales表示应用所支持的语言地区属性,而S.delegate则是Flutter i18n插件自动生成的类,包含Flutter所支持的语言地区属性以及对应的文案翻译映射。在上面的代码中,除了加入S.delegate外,还加入了GlobalMaterialLocalizations.delegate和GlobalWidgetsLocalizations.delegate这两个回调。翻译
前者为Material组件库提供的本地化的字符串和其余值,它可使组件支持多语言,然后者则是用于定义组件默认的文本方向,从左到右或从右到左。之因此要加入这两个回调,是由于Flutter提供的组件自己已经支持了国际化,因此不必再适配一遍。而参数supportedLocales则用于表示应用所支持的语言地区,它的格式以下。3d
const Locale('zh', 'CN') //中文简体
其中,Locale类是用来标识用户语言环境的,它由语言和国家两个属性构成。在上面的代码中,咱们将它设置成S.delegate.supportedLocales,即当前设备的语言。完成上述应用程序的国际化配置操做后,接下来就能够在程序中经过S.of(context)方式获取arb文件中的内容了。下面是使用S.of(context)方式获取arb文件中标题名字的例子,以下所示。代理
S.of(context).main_title //获取标题
须要说明的是,使用上面的方式获取翻译文案的内容须要在能获取到上下文的前提下才能生效,也就是说只能对MaterialApp的子组件才会生效。所以,若是要对应用的标题进行国际化配置,直接使用上面的方式是不行的,不过可使用MaterialApp提供的onGenerateTitle回调方法来进行处理,以下所示。
onGenerateTitle: (context) { return S.of(context).app_name; },
对于应用界面文案的国际化则要相对简单许多,直接使用S.of(context)方式拿到arb文件中翻译文案,而后设置到界面便可。下面是对Flutter官方工程的国际化处理,代码以下。
Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text(S.of(context).main_title), centerTitle: true, ), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ Text(S.of(context).main_content), Text('$_counter', style: Theme.of(context).textTheme.display1), ], ), ), floatingActionButton: FloatingActionButton( onPressed: _incrementCounter, tooltip: 'Increment', child: Icon(Icons.add), ), ); }
接下来,切换系统中的英文和中文,而后运行上面的代码,能够看到,应用的内容会随着系统的语言进行切换,效果下图所示。
不过,因为iOS应用程序有一套自建的语言环境管理机制,因此使用上面的方式适配国际化对于iOS应用程序是无效的。为了让iOS应用程序也能支持国际化,还须要在原生iOS工程中进行额外的配置。
使用Xcode打开Flutter项目的iOS原生工程,切换到工程面板,而后在Localization选项配置中添加中文支持,以下图所示。
完成上述iOS原生工程配置后,再次回到Flutter工程,选择iOS模拟器运行程序,就能够看到能够正常的支持国际化了,以下图所示。能够发行,国际化的核心就是语言差别配置抽取。与Flutter的国际化处理方式不一样,原生Android和iOS应用适配国际化只须要按照要求将国际化资源放到对应的文件夹目录,而后应用层代码访问国际化资源时就会自动根据语言地区进行适配。