详解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判断屏幕分辨率的代码
Jul 16 Javascript
js判断数据类型如判断是否为数组是否为字符串等等
Jan 15 Javascript
JavaScript获取图片的原始尺寸以宽度为例
May 04 Javascript
JS来动态的修改url实现对url的增删查改
Sep 05 Javascript
js实现按钮颜色渐变动画效果
Aug 20 Javascript
JS实现IE状态栏文字缩放效果代码
Oct 24 Javascript
跟我学习javascript的定时器
Nov 19 Javascript
form+iframe解决跨域上传文件的方法
Nov 18 Javascript
为vue-router懒加载时下载js的过程中添加loading提示避免无响应问题
Apr 03 Javascript
JavaScript树的深度优先遍历和广度优先遍历算法示例
Jul 30 Javascript
js中位运算的运用实例分析
Dec 11 Javascript
vue动态绘制四分之三圆环图效果
Sep 03 Javascript
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
《斗罗大陆》六翼天使武魂最强,为什么老千家不是上三宗?
2020/03/02 国漫
php函数指定默认值方法的小例子
2013/12/04 PHP
PHP实现提高SESSION响应速度的几种方法详解
2019/08/09 PHP
脚本吧 - 幻宇工作室用到js,超强推荐base.js
2006/12/23 Javascript
javascript 获取表单file全路径
2009/12/31 Javascript
Extjs改变树节点的勾选状态点击按钮将复选框去掉
2013/11/14 Javascript
JS计算网页停留时间代码
2014/04/28 Javascript
js检测网络是否具体连接功能的代码
2014/05/23 Javascript
JavaScript中的console.profile()函数详细介绍
2014/12/29 Javascript
JavaScript中使用Object.prototype.toString判断是否为数组
2015/04/01 Javascript
浅谈JavaScript中null和undefined
2015/07/09 Javascript
分享我对JS插件开发的一些感想和心得
2016/02/04 Javascript
ionic js 复选框 与普通的 HTML 复选框到底有没区别
2016/06/06 Javascript
再谈Javascript中的异步以及如何异步
2016/08/19 Javascript
基于ajax与msmq技术的消息推送功能实现代码
2016/12/26 Javascript
老生常谈js中0到底是 true 还是 false
2017/03/08 Javascript
xmlplus组件设计系列之图标(ICON)(1)
2017/05/05 Javascript
JavaScript获取tr td 的三种方式全面总结(推荐)
2017/08/15 Javascript
详解基于node.js的脚手架工具开发经历
2019/01/28 Javascript
微信小程序 自定义复选框实现代码实例
2019/09/04 Javascript
解决layui数据表格Date日期格式的回显Object的问题
2019/09/19 Javascript
vue + elementUI实现省市县三级联动的方法示例
2019/10/29 Javascript
原生JavaScript实现留言板
2021/01/10 Javascript
vite2.0+vue3移动端项目实战详解
2021/03/03 Vue.js
Python基于list的append和pop方法实现堆栈与队列功能示例
2017/07/24 Python
python merge、concat合并数据集的实例讲解
2018/04/12 Python
pandas Dataframe行列读取的实例
2018/06/08 Python
Django中自定义查询对象的具体使用
2019/10/13 Python
tensorflow tf.train.batch之数据批量读取方式
2020/01/20 Python
关于django python manage.py startapp 应用名出错异常原因解析
2020/12/15 Python
2014年度党员自我评议
2014/09/13 职场文书
基层干部群众路线教育实践活动个人对照检查材料
2014/09/23 职场文书
光棍节联谊晚会活动策划书
2014/10/10 职场文书
出国签证在职证明范本
2014/11/24 职场文书
2015年度公共机构节能工作总结
2015/05/26 职场文书
2015-2016年小学教导工作总结
2015/07/21 职场文书