详解React-Native全球化多语言切换工具库react-native-i18n


Posted in Javascript onNovember 03, 2017

开篇??篓C阶段感悟

最近2 -3个月基本都因为一些私事没怎么系统的工作和学习,途中看了几天Kotlin的东西写了些demo并且整了个小项目,但是整体状态不是很好,这些天看到些95后码农的强势细思极恐。

现在大多数醒来就已经是中午,起得早去一下健身房,起的晚就家里宅一天。公司有事或者有其他家事就去协调/沟通/处理下,整个人感觉都提前进入养老状态(当然这个锅有一半是沉迷王者荣耀不可自拔,不太好)

最近项目上基本没啥事情了,然后让手下的小伙伴们对之前做的一些内容进行二次封装,然后他们引用了一个第三方国际化的库我觉得不错,然后看了看源码就分享下,希望大家用得上(虽然现在产品的受众群都是国内的,但是准备下好像没毛病?)

废话??峦炅耍?瞎婢兀?a rel="external nofollow" target="_blank" href="https://github.com/ddwhan0123/Useful-Open-Source-Android">https://github.com/ddwhan0123/Useful-Open-Source-Android (虽然我不怎么工作了,但是git还是每天会花时间看看)

库属性介绍:

项目地址:https://github.com/AlexanderZaytsev/react-native-i18n

属性 解释
支持RN版本 所有版本
支持平台 iOS+Android
是否需要NativeModule
是否可移植
是否含有jni模块

使用:

1.install (略,git里都写着了,就是npm那些事)

2.项目中使用

因为是一些静态属性引用,所以你用redux做储存替换也可以,直接做饮用也可以(本文拿en,zh为例)。

首先是建英文版本的配置文件,en/index.js

export default {
 home: {
  greeting: 'Greeting in en',
  tab_home: 'Home',
  tab_donate: 'Donate',
  tab_demo: 'Demo',
  language: 'language',
  live_demo: 'Live Demo',
  buy_me_coffee: 'Buy me a coffee',
  gitee: 'Gitee',
  star_me: 'Star me',
  donate: 'donate',
  exit: 'exit?',
 },
 donate: {
  donate: 'donate us~~~',
  donate_desc: '© 2017 Pactera Technology International Limited. All rights reserved.',
 },
 demo: {
  dialog: 'dialog',
  button: 'button',
  switch: 'switch',
  action_sheet: 'Action Sheet',
 }
};

然后是中文的zh/index.js

export default {
 home: {
  greeting: 'Greeting in zh',
  tab_home: '首页',
  tab_donate: '捐赠',
  tab_demo: '例子',
  language: '语言',
  live_demo: '例子',
  buy_me_coffee: '请我一杯coffee',
  gitee: 'Gitee',
  star_me: '关注我',
  donate: '贡献',
  exit: '是否退出?',
 },
 donate: {
  donate: '支持我们~~',
  donate_desc: '© 2017 Pactera Technology International Limited. All rights reserved.',
 },
 demo: {
  dialog: '提示框',
  button: '按钮',
  switch: '开关',
  action_sheet: '',
 }
};

属性名,结构是一致的只是属性不同,当然这里是静态的2个文件,如果场景需要可以服务端下发json,那就是完全动态的了,这部分看业务需求了。

2.1 默认的语言环境

我们在上面写了2种语言配置,那么哪种作为初始化的呢?在业务层调用前,我们可以先进行预设

i18n/index.js

import i18n from 'react-native-i18n';
import en from './en';
import zh from './zh';

i18n.defaultLocale = 'en';
i18n.fallbacks = true;
i18n.translations = {
 en,
 zh,
};

export {i18n};

这边进行了一些预设,默认语境为en,允许fallbacks状态(为true时,顺序向下遍历翻译),预设转换的文件就2个,一个en一个zh,这个你也可以自行后续添加根据需求而定。

2.2 业务层调用

先是倒包

import {i18n} from '你预设的index的目录';

调用(拿一个Toast做个例子)

ToastAndroid.show(i18n.t('home.exit'),ToastAndroid.SHORT);

两种输出结果如下:

详解React-Native全球化多语言切换工具库react-native-i18n

详解React-Native全球化多语言切换工具库react-native-i18n

源码分析

这个库的实现分为2部分,一部分是Native的版本判断等功能以及js部分的核心实现fnando/i18n-js

i18n-js是一个轻量级的js翻译库,他支持各种格式和内容的换算和语言内容的切换,地址如下:https://github.com/fnando/i18n-js

那么翻译转换这块是 I18n.js做的那么Native做了些啥呢?我们来一探究竟(以安卓为例,苹果看不懂,抱歉)

详解React-Native全球化多语言切换工具库react-native-i18n

Native代码就两个类,所以我之前说你直接把Native代码copy走然后项目依赖I18n.js也能达到这个效果

RNI18nPackage是一个普通的Package类,它的作用就是把我们的module加到主应用的getPackages()方法中的列表里,然后一起打进包里而已。

具体功能都在RNI18nModule里

public class RNI18nModule extends ReactContextBaseJavaModule {

 public RNI18nModule(ReactApplicationContext reactContext) {
 super(reactContext);
 }
 //RN调用的控件名
 @Override
 public String getName() {
 return "RNI18n";
 }

 //对取出的Locale列表进行格式化的方法
 private String toLanguageTag(Locale locale) {
 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
  return locale.toLanguageTag();
 }

 StringBuilder builder = new StringBuilder();
 builder.append(locale.getLanguage());

 if (locale.getCountry() != null) {
  builder.append("-");
  builder.append(locale.getCountry());
 }

 return builder.toString();
 }

 private WritableArray getLocaleList() {
 WritableArray array = Arguments.createArray();

 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
  //获取区域设置列表。这是获取区域的首选方法。
  LocaleList locales = getReactApplicationContext()
   .getResources().getConfiguration().getLocales();

  for (int i = 0; i < locales.size(); i++) {
  array.pushString(this.toLanguageTag(locales.get(i)));
  }
 } else {
  array.pushString(this.toLanguageTag(getReactApplicationContext()
   .getResources().getConfiguration().locale));
 }

 return array;
 }

 //js端可获取属性的列表
 @Override
 public Map<String, Object> getConstants() {
 HashMap<String, Object> constants = new HashMap<String,Object>();
 constants.put("languages", this.getLocaleList());
 return constants;
 }

 //提供给js端调用的方法,用来获取默认的语言环境,回调方式用的是promise
 @ReactMethod
 public void getLanguages(Promise promise) {
 try {
  promise.resolve(this.getLocaleList());
 } catch (Exception e) {
  promise.reject(e);
 }
 }
}

加一个toast看下locale会出现什么

Toast.makeText(getReactApplicationContext(),"locales.get(i) "+locales.get(i),Toast.LENGTH_LONG).show();

效果如下:

详解React-Native全球化多语言切换工具库react-native-i18n

本想一探究竟内部的实现,结果是个不公开的类

详解React-Native全球化多语言切换工具库react-native-i18n

总结:

首先Native那里获取本手机的LocaleList然后格式化取第一个元素交由I18n.js处理,然后I18n.js根据key选用一套有效的语言规则,再之后流程就和使用时候的顺序一样了。
整个库集成难度较低,使用起来比较简便,使用下来没碰到大坑,配合redux更美味。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
用js实现多域名不同文件的调用方法
Jan 12 Javascript
纯JavaScript实现的完美渐变弹出层效果代码
Apr 02 Javascript
jQuery之过滤元素操作小结
Nov 30 Javascript
项目中常用的JS方法整理
Jan 30 Javascript
jquery实现平滑的二级下拉菜单效果
Aug 26 Javascript
ES6教程之for循环和Map,Set用法分析
Apr 10 Javascript
原生JS实现小小的音乐播放器
Oct 16 Javascript
理解 JavaScript EventEmitter
Mar 29 Javascript
移动端 Vue+Vant 的Uploader 实现上传、压缩、旋转图片功能
Jun 10 Javascript
vue-drag-chart 拖动/缩放图表组件的实例代码
Apr 10 Javascript
原生JS实现汇率转换功能代码实例
May 13 Javascript
vue+elementUI实现表格列的显示与隐藏
Apr 13 Vue.js
js 客户端打印html 并且去掉页眉、页脚的实例
Nov 03 #Javascript
微信小程序自动客服功能
Nov 02 #Javascript
微信小程序选择图片和放大预览图片功能
Nov 02 #Javascript
微信小程序实现图片放大预览功能
Oct 22 #Javascript
极简主义法编写JavaScript类
Nov 02 #Javascript
利用nvm管理多个版本的node.js与npm详解
Nov 02 #Javascript
JavaScript屏蔽Backspace键的实现代码
Nov 02 #Javascript
You might like
据说是雅虎的一份PHP面试题附答案
2009/01/07 PHP
探讨如何把session存入数据库
2013/06/07 PHP
PHP使用Memcache时模拟命名空间及缓存失效问题的解决
2016/02/27 PHP
php提高脚本性能的4个技巧
2020/08/18 PHP
判断目标是否是window,document,和拥有tagName的Element的代码
2010/05/31 Javascript
Jquery阻止事件冒泡 event.stopPropagation
2011/12/11 Javascript
jQuery写的日历(包括日历的样式及功能)
2013/04/23 Javascript
javascript中自定义对象的属性方法分享
2013/07/12 Javascript
JS获取地址栏参数的小例子
2013/08/23 Javascript
jquery数组之存放checkbox全选值示例代码
2013/12/20 Javascript
SinaEditor使用方法详解
2013/12/28 Javascript
js简单实现交换Li的值
2014/05/22 Javascript
字段太多jquey快速清空表单内容方法
2014/08/21 Javascript
JavaScript lastIndexOf方法入门实例(计算指定字符在字符串中最后一次出现的位置)
2014/10/17 Javascript
Node.js实现批量去除BOM文件头
2014/12/20 Javascript
JQuery中DOM加载与事件执行实例分析
2015/06/13 Javascript
基于jQuery实现的向下滑动二级菜单效果代码
2015/08/31 Javascript
AngularJS 验证码60秒倒计时功能的实现
2017/06/05 Javascript
微信小程序新手教程之启动页的重要性
2019/03/03 Javascript
js前端面试之同步与异步问题详解
2019/04/03 Javascript
微信小程序 this.triggerEvent()的具体使用
2019/12/10 Javascript
使用typescript改造koa开发框架的实现
2020/02/04 Javascript
[02:57]DOTA2英雄基础教程 风行者
2014/01/16 DOTA
pycharm 使用心得(一)安装和首次使用
2014/06/05 Python
python3+PyQt5泛型委托详解
2018/04/24 Python
python实现K近邻回归,采用等权重和不等权重的方法
2019/01/23 Python
python assert的用处示例详解
2019/04/01 Python
pandas实现DataFrame显示最大行列,不省略显示实例
2019/12/26 Python
python 双循环遍历list 变量判断代码
2020/05/04 Python
python实现一次性封装多条sql语句(begin end)
2020/06/06 Python
keras 自定义loss model.add_loss的使用详解
2020/06/22 Python
Python钉钉报警及Zabbix集成钉钉报警的示例代码
2020/08/17 Python
某公司Java工程师面试题笔试题
2016/03/27 面试题
鼓舞士气的口号
2014/06/16 职场文书
企业党员个人自我评价
2014/09/20 职场文书
2017新年晚会开幕词
2016/03/03 职场文书