赵走x博客
网站访问量:151485
首页
书籍
软件
工具
古诗词
搜索
登录
75、插件开发:iOS端API实现
64、文件操作
85、图片加载原理与缓存
84、Flutter运行机制-从启动到显示
83、RenderObject和RenderBox
82、Element与BuildContext
81、Flutter UI系统
80、国际化常见问题
79、使用Intl包
78、实现Localizations
77、让App支持多语言
76、Texture和PlatformView
73、开发Flutter插件
72、插件开发:平台通道简介
71、开发Package
70、Json转Dart Model类
69、使用Socket API
68、使用WebSockets
67、实例:Http分块下载
66、Http请求-Dio http库
65、通过HttpClient发起HTTP请求
63、自绘实例:圆形背景渐变进度条
62、自绘组件 (CustomPaint与Canvas)
61、组合实例:TurnBox
60、组合现有组件
59、自定义组件方法简介
58、动画过渡组件
57、通用"切换动画"组件(AnimatedSwitcher)
56、交织动画
55、Hero动画
54、自定义路由切换动画
53、动画基本结构及状态监听
51、动画
50、通知(Notification)
49、全局事件总线
48、手势识别
47、原始指针事件处理
46、事件处理与通知
45、对话框详解
44、异步UI更新(FutureBuilder、StreamBuilder)
43、颜色和主题
42、跨组件状态共享(Provider)
41、数据共享(InheritedWidget)
40、导航返回拦截(WillPopScope)
39、功能型Widget简介
38、滚动监听及控制
37、CustomScrollView
36、GridView
35、ListView
34、SingleChildScrollView
33、可滚动组件简介
32、剪裁(Clip)
31、Scaffold、TabBar、底部导航
30、Container
29、变换(Transform)
28、装饰容器DecoratedBox
27、尺寸限制类容器
26、填充(Padding)
25、容器类Widget
24、对齐与相对定位(Align)
23、层叠布局 Stack、Positioned
22、流式布局
21、弹性布局(Flex)
20、线性布局(Row和Column)
19、布局类组件简介
18、进度指示器
17、输入框及表单
16、单选开关和复选框
15、图片及ICON
14、按钮
13、文本、字体样式
12、状态管理
11、Widget简介
10、Flutter异常捕获
9、调试Flutter应用
8、资源管理
7、包管理
6、路由管理
5、第一个Flutter应该:计数器应用示例
4、Dart语言简介
3、搭建Flutter开发环境
2、初识Flutter
1、移动开发技术简介
79、使用Intl包
资源编号:76233
Flutter实战
书籍
热度:135
使用Intl包我们不仅可以非常轻松的实现国际化,而且也可以将字符串文本分离成单独的文件,方便开发人员和翻译人员分工协作。
使用Intl包我们不仅可以非常轻松的实现国际化,而且也可以将字符串文本分离成单独的文件,方便开发人员和翻译人员分工协作。为了使用Intl包我们需要添加两个依赖: ``` dependencies: #...省略无关项 intl: ^0.15.7 dev_dependencies: #...省略无关项 intl_translation: ^0.17.2 ``` intl_translation 包主要包含了一些工具,它在开发阶段主要主要的作用是从代码中提取要国际化的字符串到单独的arb文件和根据arb文件生成对应语言的dart代码,而intl包主要是引用和加载intl_translation生成后的dart代码。下面我们将一步步来说明如何使用: # 第一步:创建必要目录 首先,在项目根目录下创建一个i10n-arb目录,该目录保存我们接下来通过intl_translation命令生成的arb文件。一个简单的arb文件内容如下: ``` { "@@last_modified": "2018-12-10T15:46:20.897228", "@@locale":"zh_CH", "title": "Flutter应用", "@title": { "description": "Title for the Demo application", "type": "text", "placeholders": {} } } ``` 我们根据"@@locale"字段可以看出这个arb对应的是中文简体的翻译,里面的title字段对应的正是我们应用标题的中文简体翻译。@title字段是对title的一些描述信息。 接下来,我们在lib目录下创建一个i10n的目录,该目录用于保存从arb文件生成的dart代码文件。 # 第二步:实现Localizations和Delegate类 和上一节中的步骤类似,我们仍然要实现Localizations和Delegate类,不同的是,现在我们在实现时要使用intl包的一些方法(有些是动态生成的)。 下面我们在lib/i10n目录下新建一个“localization_intl.dart”的文件,文件内容如下: ``` import 'package:flutter/material.dart'; import 'package:intl/intl.dart'; import 'messages_all.dart'; //1 class DemoLocalizations { static Future
load(Locale locale) { final String name = locale.countryCode.isEmpty ? locale.languageCode : locale.toString(); final String localeName = Intl.canonicalizedLocale(name); //2 return initializeMessages(localeName).then((b) { Intl.defaultLocale = localeName; return new DemoLocalizations(); }); } static DemoLocalizations of(BuildContext context) { return Localizations.of
(context, DemoLocalizations); } String get title { return Intl.message( 'Flutter APP', name: 'title', desc: 'Title for the Demo application', ); } } //Locale代理类 class DemoLocalizationsDelegate extends LocalizationsDelegate
{ const DemoLocalizationsDelegate(); //是否支持某个Local @override bool isSupported(Locale locale) => ['en', 'zh'].contains(locale.languageCode); // Flutter会调用此类加载相应的Locale资源类 @override Future
load(Locale locale) { //3 return DemoLocalizations.load(locale); } // 当Localizations Widget重新build时,是否调用load重新加载Locale资源. @override bool shouldReload(DemoLocalizationsDelegate old) => false; } ``` 注意: * 注释1的"messages_all.dart"文件是通过intl_translation工具从arb文件生成的代码,所以在第一次运行生成命令之前,此文件不存在。注释2处的initializeMessages()方法和"messages_all.dart"文件一样,是同时生成的。 * 注释3处和上一节示例代码不同,这里我们直接调用DemoLocalizations.load()即可。 # 第三步:添加需要国际化的属性 现在我们可以在DemoLocalizations类中添加需要国际化的属性或方法,如上面示例代码中的title属性,这时我们就要用到Intl库提供的一些方法,这些方法可以帮我们轻松实现不同语言的一些语法特性,如复数语境,举个例子,比如我们有一个电子邮件列表页,我们需要在顶部显示未读邮件的数量,在未读数量不同事,我们展示的文本可能会不同: | 未读邮件数 | 提示语 | | ------------ | ------------ | | 0 |There are no emails left| |1| There is 1 email left| |n(n>1) |There are n emails left| 我们可以通过Intl.plural(...)来实现: ``` remainingEmailsMessage(int howMany) => Intl.plural(howMany, zero: 'There are no emails left', one: 'There is $howMany email left', other: 'There are $howMany emails left', name: "remainingEmailsMessage", args: [howMany], desc: "How many emails remain after archiving.", examples: const {'howMany': 42, 'userName': 'Fred'}); ``` 可以看到通过Intl.plural方法可以在howMany值不同时输出不同的提示信息。 Intl包还有一些其他的方法,读者可以自行查看其文档,本书不在赘述。 # 第四步:生成arb文件 现在我们可以通intl_translation包的工具来提取代码中的字符串到一个arb文件,运行如下命名: ``` flutter pub pub run intl_translation:extract_to_arb --output-dir=i10n-arb \ lib/i10n/localization_intl.dart ``` 运行此命令后,会将我们之前通过Intl API标识的属性和字符串提取到“i10n-arb/intl_messages.arb”文件中,我们看看其内容: ``` { "@@last_modified": "2018-12-10T17:37:28.505088", "title": "Flutter APP", "@title": { "description": "Title for the Demo application", "type": "text", "placeholders": {} }, "remainingEmailsMessage": "{howMany,plural, =0{There are no emails left}=1{There is {howMany} email left}other{There are {howMany} emails left}}", "@remainingEmailsMessage": { "description": "How many emails remain after archiving.", "type": "text", "placeholders": { "howMany": { "example": 42 } } } } ``` 这个是默认的Locale资源文件,如果我们现在要支持中文简体,只需要在该文件同级目录创建一个"intl_zh_CN.arb"文件,然后将"intl_messages.arb"的内容拷贝到"intl_zh_CN.arb"文件,接下来将英文翻译为中文即可,翻译后的"intl_zh_CN.arb"文件内容如下: ``` { "@@last_modified": "2018-12-10T15:46:20.897228", "@@locale":"zh_CN", "title": "Flutter应用", "@title": { "description": "Title for the Demo application", "type": "text", "placeholders": {} }, "remainingEmailsMessage": "{howMany,plural, =0{没有未读邮件}=1{有{howMany}封未读邮件}other{有{howMany}封未读邮件}}", "@remainingEmailsMessage": { "description": "How many emails remain after archiving.", "type": "text", "placeholders": { "howMany": { "example": 42 } } } } ``` 我们必须要翻译title和remainingEmailsMessage字段,description是该字段的说明,通常给翻译人员看,代码中不会用到。 有两点需要说明: * 1.如果某个特定的arb中缺失某个属性,那么应用将会加载默认的arb文件(intl_messages.arb)中的相应属性,这是Intl的托底策略。 * 2.每次运行提取命令时,intl_messages.arb都会根据代码重新生成,但其他arb文件不会,所以当要添加新的字段或方法时,其他arb文件是增量的,不用担心会覆盖。 * 3.arb文件是标准的,其格式规范可以自行了解。通常会将arb文件交给翻译人员,当他们完成翻译后,我们再通过下面的步骤根据arb文件生成最终的dart代码。 # 第五步:生成dart代码 最后一步就是根据arb生成dart文件: ``` flutter pub pub run intl_translation:generate_from_arb --output-dir=lib/i10n --no-use-deferred-loading lib/i10n/localization_intl.dart i10n-arb/intl_*.arb ``` 这句命令在首次运行时会在"lib/i10n"目录下生成多个文件,对应多种Locale,这些代码便是最终要使用的dart代码。 # 总结 至此,我们将使用Intl包对APP进行国际化的流程介绍完了,我们可以发现,其中第一步和第二步只在第一次需要,而我们开发时的主要的工作都是在第三步。由于最后两步在第三步完成后每次也都需要,所以我们可以将最后两步放在一个shell脚本里,当我们完成第三步或完成arb文件翻译后只需要分别执行该脚本即可。我们在根目录下创建一个intl.sh的脚本,内容为: ``` flutter pub pub run intl_translation:extract_to_arb --output-dir=i10n-arb lib/i10n/localization_intl.dart flutter pub pub run intl_translation:generate_from_arb --output-dir=lib/i10n --no-use-deferred-loading lib/i10n/localization_intl.dart i10n-arb/intl_*.arb ``` 然后授予执行权限: ``` chmod +x intl.sh ``` 执行intl.sh ``` ./intl.sh ```