热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Flutter怎么样做国际化

什么是国际化国际化是指在设计软件时,将软件与特定语言及地区脱钩的过程。当软件被移植到不同的语言地区时,软件本身不用做内部工程上的改变或修正。本地化则是指当

什么是国际化

国际化是指在设计软件时,将软件与特定语言及地区脱钩的过程。当软件被移植到不同的语言地区时,软件本身不用做内部工程上的改变或修正。

本地化则是指当移植软件时,加上与特定区域设置有关的资讯和翻译文件的过程。 国际化和本地化之间的区别虽然微妙,但却很重要。国际化意味着产品有适用于任何地方的潜力;本地化则是为了更适合于特定地方的使用,而另外增添的特色。用一项产品来说,国际化只需做一次,但本地化则要针对不同的区域各做一次。 这两者之间是互补的,并且两者结合起来才能让一个系统适用于各地。

国际化实现中的困难

开发软件时,国际化和本地化对开发者是一个有挑战性的任务,特别是当软件当初设计时没有考虑这个问题时。通常做法是将文本和其他环境相关的资源与程序代码相分离。这样在理想的情况下,应对变化的环境时无需修改代码,只要修改资源,从而显著简化了工作。

Flutter的国际化

Flutter中的国际化包括Flutter组件的国际化和其他文本的国际化两者;

Flutter组件的国际化

Flutter给我们提供的Widget默认情况下就是支持国际化,但是在没有进行特别的设置之前,它们无论在什么环境都是以英文的方式显示的。

如果想要添加其他语言,你的应用必须指定额外的 MaterialApp 属性并且添加一个单独的 package,叫做 flutter_localizations

截至 2020 年 11 月,该软件包支持 78 种语言。

pubspec添加依赖

想要使用 flutter_localizations 的话,我们需要在 pubspec.yaml 文件中添加它作为依赖:

dependencies: flutter: sdk: flutter flutter_localizations: sdk: flutter

设置MaterialApp

  • 在localizationsDelegates中指定哪些Widget需要进行国际化

    • 用于生产本地化值集合的工厂
    • 我们这里指定了Material、Widgets、Cupertino都使用国际化
  • supportedLocales指定要支持哪些国际化

    • 我们这里指定中文和英文(也可以指定国家编码)

MaterialApp( localizationsDelegates: [ GlobalMaterialLocalizations.delegate, // 指定本地化的字符串 GlobalCupertinoLocalizations.delegate, // 对应的Cupertino风格 GlobalWidgetsLocalizations.delegate // 指定默认的文本排列方向, 由左到右或由右到左 ], supportedLocales: [ Locale("en"), Locale("zh") ], )

注意:如果要指定语言代码、文字代码和国家代码,可以进行如下指定方式:

// Full Chinese support for CN, TW, and HK supportedLocales: [ const Locale.fromSubtags(languageCode: 'zh'), // generic Chinese 'zh' const Locale.fromSubtags(languageCode: 'zh', scriptCode: 'Hans'), // generic simplified Chinese 'zh_Hans' const Locale.fromSubtags(languageCode: 'zh', scriptCode: 'Hant'), // generic traditional Chinese 'zh_Hant' const Locale.fromSubtags(languageCode: 'zh', scriptCode: 'Hans', countryCode: 'CN'), // 'zh_Hans_CN' const Locale.fromSubtags(languageCode: 'zh', scriptCode: 'Hant', countryCode: 'TW'), // 'zh_Hant_TW' const Locale.fromSubtags(languageCode: 'zh', scriptCode: 'Hant', countryCode: 'HK'), // 'zh_Hant_HK' ],

Flutter中自定义文本的国际化

创建本地化类

该类用于定义我们需要进行本地化的字符串等信息:

  • 1.我们需要一个构造器,并且传入一个Locale对象
  • 2.定义一个Map,其中存放我们不同语言对应的文本
  • 3.定义它们对应的getter方法,根据语言环境返回不同的结果

import 'package:flutter/material.dart'; class QWLocalizations { final Locale locale; QWLocalizations(this.locale); static Map> _localizedValues = { "fr": {"title": "Titre", "hello": "Bonjour"}, "zh": {"title": "首页", "hello": "你好"} }; String get title { return _localizedValues[locale.languageCode]?["title"] ?? 'title'; } String get hello { return _localizedValues[locale.languageCode]?["hello"] ?? 'hello'; } static QWLocalizations of(BuildContext context) { return Localizations.of(context, QWLocalizations); } }

自定义Delegate

上面的类定义好后,我们在什么位置或者说如何对它进行初始化呢?
我们可以像Flutter Widget中的国际化方式一样对它们进行初始化,也就是我们可以定义一个对象的Delegate类,并且将其传入localizationsDelegates中;

Delegate的作用就是当Locale发生改变时,调用对应的load方法,重新加载新的Locale资源

HYLocalizationsDelegate需要继承自LocalizationsDelegate,并且有三个方法必须重写:
isSupported,shouldReload,load

import 'package:flutter/cupertino.dart'; import 'package:flutter/foundation.dart'; import 'QWLocalizations.dart'; class QWLocalizationsDelegate extends LocalizationsDelegate { //是否在我们支持的语言范围 @override bool isSupported(Locale locale) { return ["fr", "zh"].contains(locale.languageCode); } /* * 当Localizations Widget重新build时,是否调用load方法重新加载Locale资源 一般情况下,Locale资源只应该在Locale切换时加载一次,不需要每次Localizations重新build时都加载一遍; 所以一般情况下返回false即可; * */ @override bool shouldReload(LocalizationsDelegate old) { return false; } /* * 当Locale发生改变时(语言环境),加载对应的HYLocalizations资源 这个方法返回的是一个Future,因为有可能是异步加载的; 但是我们这里是直接定义的一个Map,因此可以直接返回一个同步的Future(SynchronousFuture) * */ @override Future load(Locale locale) { return SynchronousFuture(QWLocalizations(locale)); } static QWLocalizationsDelegate delegate = QWLocalizationsDelegate(); }

异步加载数据

假如我们的数据是异步加载的,比如来自Json文件或者服务器,应该如何处理呢?

QWLocalizations类中如下面代码:

static Map> _localizedValues = {}; Future loadJson() async { // 1.加载json文件 String jsOnString= await rootBundle.loadString("assets/json/i18n.json"); // 2.转成map类型 final Map map = json.decode(jsonString); // 3.注意:这里是将Map转成Map>类型 _localizedValues = map.map((key, value) { return MapEntry(key, value.cast()); }); return true; }

在QWLocalizationsDelegate中使用异步进行加载:

@override Future load(Locale locale) async { final localization = QWLocalizations(locale); await localization.loadJson(); return localization; }

使用本地化类

接着我们可以在代码中使用HYLocalization类。

  • 我们可以通过QWLocalizations.of(context)获取到QWLocalizations对象

Text( QWLocalizations.of(context).hello, )

国际化的工具—Intl

认识arb文件

目前我们已经可以通过加载对应的json文件来进行本地化了。

但是还有另外一个问题,我们在进行国际化的过程中,下面的代码依然需要根据json文件手动编写

String get title { return _localizedValues[locale.languageCode]?["title"] ?? 'title'; } String get hello { return _localizedValues[locale.languageCode]?["hello"] ?? 'hello'; }

有没有一种更好的方式,让我们可以快速在本地化文件即dart代码文件直接来转换呢?答案就是arb文件

  • arb文件全称Application Resource Bundle,表示应用资源包,目前已经得到Google的支持;
  • 其本质就是一个json文件,但是可以根据该文件转成对应的语言环境;
  • arb的说明文档:https://github.com/google/app-r

使用IDE插件来进行arb和dart文件之间的转换

  • 初始化intl

选择工具栏Tools – Flutter Intl – Initialize for the Project

Flutter怎么样做国际化
image.png

完成上面的操作之后会自动生成如下文件目录:

  • generated是自动生成的dart代码
  • I10n是对应的arb文件目录
Flutter怎么样做国际化
image.png

使用intl

在localizationsDelegates中配置生成的class,名字是S

  • 1.添加对应的delegate
  • 2.supportedLocales使用S.delegate.supportedLocales

localizationsDelegates: [ GlobalMaterialLocalizations.delegate, GlobalWidgetsLocalizations.delegate, GlobalCupertinoLocalizations.delegate, S.delegate ], supportedLocales: S.delegate.supportedLocales,

因为我们目前还没有对应的本地化字符串,所以需要在intl_en.arb文件中编写:

{ "title": "home", "hello": "hello" }

  • 编写后ctrl(command) + s保存即可;

之后按照如下格式在代码中使用

S.of(context).title

添加中文

如果希望添加中文支持:add local

Flutter怎么样做国际化
image.png
  • 在弹出框中输入zh即可

我们会发现,会生成对应的intl_zh.arb和messages_zh.dart文件

Flutter怎么样做国际化
image.png

arb其它语法

如果我们希望在使用本地化的过程中传递一些参数:

  • 比如hello kobe或hello james
  • 比如你好啊,李银河或你好啊,王小波

修改对应的arb文件:

  • {name}:表示传递的参数

{ "title": "home", "hello": "hello", "sayHello": "hello {name}" }

在使用时,传入对应的参数即可:

Text(S.of(context).sayHello("李银河")),

总结

文本的国际化实质就是根据系统提供的locale信息去获取对应的文本和对UI做相应操作(指从左到右还是从右到左展示),locale信息是指国家代码、地区代码等,通常我们本地需要做的就是把文案按照{国家代码:{通用文本:本地化文案}}的格式进行组织排列。这里国家代码比如中国是zh,美国是en。通用文本一般用英文。最后就是根据locale信息和通用文本去字典获取本地化文本值的过程。

参考:

Flutter国际化

https://zhuanlan.zhihu.com/p/145992691


推荐阅读
  • JUC(三):深入解析AQS
    本文详细介绍了Java并发工具包中的核心类AQS(AbstractQueuedSynchronizer),包括其基本概念、数据结构、源码分析及核心方法的实现。 ... [详细]
  • 本文详细介绍了 PHP 中对象的生命周期、内存管理和魔术方法的使用,包括对象的自动销毁、析构函数的作用以及各种魔术方法的具体应用场景。 ... [详细]
  • 本指南介绍了如何在ASP.NET Web应用程序中利用C#和JavaScript实现基于指纹识别的登录系统。通过集成指纹识别技术,用户无需输入传统的登录ID即可完成身份验证,从而提升用户体验和安全性。我们将详细探讨如何配置和部署这一功能,确保系统的稳定性和可靠性。 ... [详细]
  • 本文介绍了在 Java 编程中遇到的一个常见错误:对象无法转换为 long 类型,并提供了详细的解决方案。 ... [详细]
  • [转]doc,ppt,xls文件格式转PDF格式http:blog.csdn.netlee353086articledetails7920355确实好用。需要注意的是#import ... [详细]
  • 深入剖析Java中SimpleDateFormat在多线程环境下的潜在风险与解决方案
    深入剖析Java中SimpleDateFormat在多线程环境下的潜在风险与解决方案 ... [详细]
  • MATLAB字典学习工具箱SPAMS:稀疏与字典学习的详细介绍、配置及应用实例
    SPAMS(Sparse Modeling Software)是一个强大的开源优化工具箱,专为解决多种稀疏估计问题而设计。该工具箱基于MATLAB,提供了丰富的算法和函数,适用于字典学习、信号处理和机器学习等领域。本文将详细介绍SPAMS的配置方法、核心功能及其在实际应用中的典型案例,帮助用户更好地理解和使用这一工具箱。 ... [详细]
  • 使用Maven JAR插件将单个或多个文件及其依赖项合并为一个可引用的JAR包
    本文介绍了如何利用Maven中的maven-assembly-plugin插件将单个或多个Java文件及其依赖项打包成一个可引用的JAR文件。首先,需要创建一个新的Maven项目,并将待打包的Java文件复制到该项目中。通过配置maven-assembly-plugin,可以实现将所有文件及其依赖项合并为一个独立的JAR包,方便在其他项目中引用和使用。此外,该方法还支持自定义装配描述符,以满足不同场景下的需求。 ... [详细]
  • 在Android 4.4系统中,通过使用 `Intent` 对象并设置动作 `ACTION_GET_CONTENT` 或 `ACTION_OPEN_DOCUMENT`,可以从相册中选择图片并获取其路径。具体实现时,需要为 `Intent` 添加相应的类别,并处理返回的 Uri 以提取图片的文件路径。此方法适用于需要从用户相册中选择图片的应用场景,能够确保兼容性和用户体验。 ... [详细]
  • 在处理大图片时,PHP 常常会遇到内存溢出的问题。为了避免这种情况,建议避免使用 `setImageBitmap`、`setImageResource` 或 `BitmapFactory.decodeResource` 等方法直接加载大图。这些函数在处理大图片时会消耗大量内存,导致应用崩溃。推荐采用分块处理、图像压缩和缓存机制等策略,以优化内存使用并提高处理效率。此外,可以考虑使用第三方库如 ImageMagick 或 GD 库来处理大图片,这些库提供了更高效的内存管理和图像处理功能。 ... [详细]
  • C语言中全部可用的数学函数有哪些?2.longlabs(longn);求长整型数的绝对值。3.doublefabs(doublex);求实数的绝对值。4.doublefloor(d ... [详细]
  • 实验九:使用SharedPreferences存储简单数据
    本实验旨在帮助学生理解和掌握使用SharedPreferences存储和读取简单数据的方法,包括程序参数和用户选项。 ... [详细]
  • 在软件开发过程中,经常需要将多个项目或模块进行集成和调试,尤其是当项目依赖于第三方开源库(如Cordova、CocoaPods)时。本文介绍了如何在Xcode中高效地进行多项目联合调试,分享了一些实用的技巧和最佳实践,帮助开发者解决常见的调试难题,提高开发效率。 ... [详细]
  • 卓盟科技:动态资源加载技术的兼容性优化与升级 | Android 开发者案例分享
    随着游戏内容日益复杂,资源加载过程已不仅仅是简单的进度显示,而是连接玩家与开发者的桥梁。玩家对快速加载的需求越来越高,这意味着开发者需要不断优化和提升动态资源加载技术的兼容性和性能。卓盟科技通过一系列的技术创新,不仅提高了加载速度,还确保了不同设备和系统的兼容性,为用户提供更加流畅的游戏体验。 ... [详细]
  • 在Kubernetes上部署多个Mitmproxy代理服务器以实现高效流量管理 ... [详细]
author-avatar
10灬月
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有