Flutter多语言实践

简介: Flutter的多语言文档 [英文版](https://flutter.io/tutorials/internationalization/) [中文版](http://www.cnblogs.com/rustfisher/p/9328531.html) 官方流程 --- 简单来讲,流程图如下![g1.png](https://cdn.nlark.com/lark/0/2018/png/

官方流程

简单来讲,流程图如下g1.png
简单讲一下整个流程

  1. 我们先写一个AppStrings.dart,这个文件是整个多语言的核心,生成和使用都需要这个文件。在这个文件里可以定义获得文本的api,比如
    String order_list_waiting_for_review() => Intl.message(
         'Waiting for the review',
         name: "order_list_waiting_for_review",
           locale: _localeName
       );
    
    其中,方法名和name必须保持一致(不要问我为何会有这种坑爹要求)。'Waiting for the review'是默认文案,locale是当前的locale。
    这样定义的话,可以用下面的方式获得文本
    String text = AppStrings.of(context).order_list_waiting_for_review();
    // text == "Waiting for the review"
    
    很好理解,AppStrings.of(context)就是通过context获得对应的localeAppStrings,进而获得对应的文案。
  2. 在上面以那种格式定义后,我们可以执行下面这个命令把AppStrings.dart生成intl_messages.arb
    flutter pub pub run intl_translation:extract_to_arb --output-dir=lib/l10n lib/app_strings.dart
    
    *.arb是个中间产物,其内就是JSON文本。其实会有更多附加信息,描述这个文本,不过在此省略。
    {
         
    "order_list_waiting_for_review": "Waiting for the review",
    }
    
  3. 生成的arb文件只是一种语言的,我们可以把它拷贝成N种语言对应的文件,比如intl_en.arb,intl_es.arb等,并把内容的value都替换成对应语言的文案。
  4. 然后再执行下面这个命令,生成messages_*.dart
    flutter pub pub run intl_translation:generate_from_arb --output-dir=lib/l10n \
    --no-use-deferred-loading lib/app_strings.dart lib/l10n/intl_*.arb
    
    可以看到,作为入参的是lib/app_strings.dartlib/l10n/intl_*.arb,flutter工具党确保lib/app_strings.dart中的方法名、方法中的name参数,和lib/l10n/intl_*.arb中的json的key一致的时候,才会在生成的messages_*.dart文件中加入对应的文案,缺一不可。

我们再回过头来看这段代码

String order_list_waiting_for_review() => Intl.message(
        'Waiting for the review',
        name: "order_list_waiting_for_review",
          locale: _localeName
      );

Intl.message()方法实际上是根据locale获取对应的message_*.dart文件,然后再通过name找到对应的文案返回。

  1. 当然,还需要对MaterialApp定义localizationsDelegates本地化代理supportedLocales支持的多语言,这部分在文章最开始的文档里写的很详细了,就不再赘述了。

官方方案的问题

官方的方案虽然很长很繁琐,但还是可以实现多语言的功能的,只是对于我们来讲,它存在以下几个问题:

  1. 需要在AppStrings.dart中定义文本获得的方法,一个文本就需要定义一个方法,并且方法名和name必须一致才能和arb文件一起生成最后的dart文件。一个文案对应一个方法,代码写起来很冗余,并且不利于文案的枚举使用(比如文案的key之间有关系)。和native开发之前的习惯也不同。使用和生成的逻辑放到一起,倘若有几千个文案,AppStrings.dart估计要爆表。
  2. 流程太长,不利于自动化下载语言的脚本的实现。

我们的流程

flutter2.png
起点的i18n.py是我们自己写的python脚本,一共有两个作用

  1. 从美杜莎(阿里国际化文案管理平台)上获得多语言文案,并重命名成arb文件。

    前面说到,arb文件其实是json格式的,美杜莎支持以json格式导出文本,所以我们做的只是重命名,不需要对内容进行更改。

  2. arb文件处理好后,会拿默认的(英语)文本去生成一个dart文件,这个dart文件只用来作为中间产物,不会被其他dart使用的。
    其中只包含如下内容
    ```javascript
    import 'package:intl/intl.dart';

class MessagesIndex {
String order_list_waiting_for_review() => Intl.message(
'Waiting for the review',
name: "order_list_waiting_for_review",
);
// ......
}

那么,我们继续调用生成最终产物的命令行

flutter pub pub run intl_translation:generate_from_arb --output-dir=lib/l10n \
--no-use-deferred-loading lib/messagesindex.dart lib/l10n/intl*.arb

发现文件以及其内的文案已经被正确生成了。

调用方式
-----
我之所以这样更改流程,其实只有两个目的:
1. 可以像读map一样的读取多语言文案,而不是像调用方法那样去读取。
2. 拉取、生成多语言文案的过程可以自动化。
通过上面一顿操作,生成文案的工作都被自动化搞定了,那我们只需要在`AppStrings.dart`中添加一个方法,传入name,传出想要的多语言文案即可:
```javascript
class AppStrings {
  final String _localeName;

  // ......
  static AppStrings of(BuildContext context) {
    return Localizations.of<AppStrings>(context, AppStrings);
  }

  // AppStrings.of(context).str(stringKey)
  String str(String name) {
    return Intl.message(name, name: name, locale: _localeName);
  }

  // 重写操作符,减少代码量
  // AppStrings.of(context)[stringKey]
  operator [](String messageName) => str(messageName);

}
目录
相关文章
|
4月前
|
SQL 分布式计算 大数据
Flutter技术实践问题之Flutter应用过程中的基础建设如何解决
Flutter技术实践问题之Flutter应用过程中的基础建设如何解决
36 10
|
4月前
|
新零售 前端开发 小程序
Flutter技术实践问题之基于Flutter的Canvas的应用优势如何解决
Flutter技术实践问题之基于Flutter的Canvas的应用优势如何解决
43 2
|
4月前
|
Web App开发 新零售 前端开发
Flutter技术实践问题之阿里集团内Flutter体系化建设如何解决
Flutter技术实践问题之阿里集团内Flutter体系化建设如何解决
50 1
|
4月前
|
Kubernetes Cloud Native 搜索推荐
探索云原生技术:Kubernetes入门与实践打造个性化安卓应用:从零开始的Flutter之旅
【8月更文挑战第31天】云原生技术正改变着应用开发和部署的方式。本文将带你了解云原生的基石——Kubernetes,通过实际的代码示例,从安装到部署一个简单的应用,让你迅速掌握Kubernetes的核心概念和操作方法。无论你是初学者还是有一定经验的开发者,这篇文章都将成为你进入云原生世界的桥梁。
|
5月前
|
设计模式 编解码 API
Flutter UI设计模式与实现:深入探索与实践
【7月更文挑战第20天】Flutter以其独特的声明式UI模式和丰富的UI组件库,为移动应用开发提供了强大的支持。通过深入理解Flutter的UI设计模式和实现技巧,开发者可以构建出高性能、可维护性强的UI界面。同时,随着Flutter生态的不断完善和发展,相信未来Flutter将在移动应用开发领域发挥更加重要的作用。
|
6月前
|
Dart 监控 测试技术
在Flutter开发中,注重代码质量与重构实践显得尤为重要
【6月更文挑战第11天】随着Flutter在跨平台开发的普及,保持高质量代码成为开发者关注的重点。良好的代码质量关乎应用性能、稳定性和开发效率。为提升Flutter代码质量,开发者应遵循最佳实践,编写可读性高的代码,实施代码审查和自动化测试。重构实践在应对代码复杂性时也至关重要,包括识别重构时机、制定计划、逐步操作及利用重构工具。注重代码质量和重构是Flutter开发成功的关键。
86 3
|
7月前
|
Dart 前端开发 安全
【Flutter前端技术开发专栏】Flutter中的线程与并发编程实践
【4月更文挑战第30天】本文探讨了Flutter中线程管理和并发编程的关键性,强调其对应用性能和用户体验的影响。Dart语言提供了`async`、`await`、`Stream`和`Future`等原生异步支持。Flutter采用事件驱动的单线程模型,通过`Isolate`实现线程隔离。实践中,可利用`async/await`、`StreamBuilder`和`Isolate`处理异步任务,同时注意线程安全和性能调优。参考文献包括Dart异步编程、Flutter线程模型和DevTools文档。
244 1
【Flutter前端技术开发专栏】Flutter中的线程与并发编程实践
|
7月前
|
Dart 前端开发 测试技术
【Flutter前端技术开发专栏】Flutter开发中的代码质量与重构实践
【4月更文挑战第30天】随着Flutter在跨平台开发的普及,保证代码质量成为开发者关注的重点。优质代码能确保应用性能与稳定性,提高开发效率。关键策略包括遵循最佳实践,编写可读性强的代码,实施代码审查和自动化测试。重构实践在项目扩展时尤为重要,适时重构能优化结构,降低维护成本。开发者应重视代码质量和重构,以促进项目成功。
85 0
【Flutter前端技术开发专栏】Flutter开发中的代码质量与重构实践
|
7月前
|
前端开发 Linux iOS开发
【Flutter前端技术开发专栏】Flutter在桌面应用(Windows/macOS/Linux)的开发实践
【4月更文挑战第30天】Flutter扩展至桌面应用开发,允许开发者用同一代码库构建Windows、macOS和Linux应用,提高效率并保持平台一致性。创建桌面应用需指定目标平台,如`flutter create -t windows my_desktop_app`。开发中注意UI适配、性能优化、系统交互及测试部署。UI适配利用布局组件和`MediaQuery`,性能优化借助`PerformanceLogging`、`Isolate`和`compute`。
457 0
【Flutter前端技术开发专栏】Flutter在桌面应用(Windows/macOS/Linux)的开发实践
|
7月前
|
存储 自然语言处理 API
Flutter应用的国际化支持:实现多语言环境的优雅策略
【4月更文挑战第26天】Flutter提供强大的国际化(i18n)和本地化(l10n)支持,使开发者能轻松实现应用多语言特性。通过定义`.arb`文件来管理字符串资源,使用`LocalizationsDelegate`加载资源,设置应用语言环境,以及在UI中使用`S.of(context).someString`访问字符串。进阶技巧包括字符串格式化、复数形式、双向文本和Unicode支持。充分测试确保所有语言正确显示。随着全球化需求增长,Flutter的国际化支持成为应用开发关键。