详解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 相关文章推荐
jQuery学习笔记之jQuery的动画
Dec 22 Javascript
等待指定时间后自动跳转或关闭当前页面的js代码
Jul 09 Javascript
鼠标拖拽移动子窗体的JS实现
Feb 25 Javascript
JavaScript中遍历对象的property的3种方法介绍
Dec 30 Javascript
javascript实现避免页面按钮重复提交
Jan 08 Javascript
JS实现点击文字对应DIV层不停闪动效果的方法
Mar 02 Javascript
在Docker快速部署Node.js应用的详细步骤
Sep 02 Javascript
chrome下判断点击input上标签还是其余标签的实现方法
Sep 18 Javascript
jQuery分组选择器简单用法示例
Apr 04 jQuery
Vue组件间通信 Vuex的用法解析
Aug 05 Javascript
写给新手同学的vuex快速上手指北小结
Apr 14 Javascript
vue实现员工信息录入功能
Jun 11 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
PHP中使用Imagick读取pdf并生成png缩略图实例
2015/01/21 PHP
Bootstrap+PHP实现多图上传功能实例详解
2018/04/08 PHP
使用swoole 定时器变更超时未支付订单状态的解决方案
2019/07/24 PHP
ext实现完整的登录代码
2008/08/08 Javascript
JQuery获取浏览器窗口内容部分高度的代码
2012/02/24 Javascript
第一次接触神奇的Bootstrap
2016/10/14 Javascript
webpack学习笔记之代码分割和按需加载的实例详解
2017/07/20 Javascript
jQuery实现IE输入框完成placeholder标签功能的方法
2017/09/20 jQuery
angular之ng-template模板加载
2017/11/09 Javascript
js实现一个页面多个倒计时的3种方法
2019/02/25 Javascript
layui.tree组件的使用以及搜索节点功能的实现
2019/09/26 Javascript
JavaScript常用进制转换及位运算实例解析
2020/10/14 Javascript
关于IDEA中的.VUE文件报错 Export declarations are not supported by current JavaScript version
2020/10/17 Javascript
ant-design表单处理和常用方法及自定义验证操作
2020/10/27 Javascript
在vue中使用vant TreeSelect分类选择组件操作
2020/11/02 Javascript
vue 数据双向绑定的实现方法
2021/03/04 Vue.js
python中管道用法入门实例
2015/06/04 Python
python模拟Django框架实例
2016/05/17 Python
谈一谈基于python的面向对象编程基础
2019/05/21 Python
Django对models里的objects的使用详解
2019/08/17 Python
Python利用for循环打印星号三角形的案例
2020/04/12 Python
keras训练浅层卷积网络并保存和加载模型实例
2020/07/02 Python
一篇文章带你搞定Ubuntu中打开Pycharm总是卡顿崩溃
2020/11/02 Python
浅谈html5之sse服务器发送事件EventSource介绍
2017/08/28 HTML / CSS
通信生自我鉴定
2014/01/18 职场文书
小学校园活动策划
2014/01/30 职场文书
护理专业求职信
2014/06/15 职场文书
班风口号
2014/06/18 职场文书
自强自立美德少年事迹材料
2014/08/16 职场文书
党的群众路线教育实践活动对照检查材料
2014/09/22 职场文书
销售业务员岗位职责
2015/02/13 职场文书
论文答辩开场白大全
2015/05/27 职场文书
婚宴领导致辞
2015/07/28 职场文书
2019年房屋委托租赁合同范本(通用版)!
2019/07/17 职场文书
OpenCV-Python实现怀旧滤镜与连环画滤镜
2021/06/09 Python
Go并发4种方法简明讲解
2022/04/06 Golang