详解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日期选择器并自动加入到输入框中示例代码
Aug 02 Javascript
JavaScript实现简单的时钟实例代码
Nov 23 Javascript
深入理解JavaScript编程中的同步与异步机制
Jun 24 Javascript
BootStrap 轮播插件(carousel)支持左右手势滑动的方法(三种)
Jul 07 Javascript
解析jQueryEasyUI的使用
Nov 22 Javascript
Javascript 制作图形验证码实例详解
Dec 22 Javascript
jQuery表格(Table)基本操作实例分析
Mar 10 Javascript
ES6学习教程之对象的扩展详解
May 02 Javascript
JS实现的四级密码强度检测功能示例
May 11 Javascript
BootStrap自定义popover,点击区域隐藏功能的实现
Jan 23 Javascript
jQuery md5加密插件jQuery.md5.js用法示例
Aug 24 jQuery
vue里面使用mui的弹出日期选择插件实例
Sep 16 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如何解决无法上传大于8M的文件问题
2014/03/10 PHP
PHP+MySQL统计该库中每个表的记录数并按递减顺序排列的方法
2016/02/15 PHP
Laravel手动分页实现方法详解
2016/10/09 PHP
PHP编程计算文件或数组中单词出现频率的方法
2017/05/22 PHP
jquery下利用jsonp跨域访问实现方法
2010/07/29 Javascript
详解强大的jQuery选择器之基本选择器、层次选择器
2012/02/07 Javascript
PHPMyAdmin导入时提示文件大小超出PHP限制的解决方法
2015/03/30 Javascript
javascript中setInterval的用法
2015/07/19 Javascript
jQuery焦点图轮播特效代码分享(3款)
2015/09/05 Javascript
JS实现的左侧竖向滑动菜单效果代码
2015/10/19 Javascript
JavaScript知识点总结(十六)之Javascript闭包(Closure)代码详解
2016/05/31 Javascript
关于List.ToArray()方法的效率测试
2016/09/30 Javascript
vuejs2.0子组件改变父组件的数据实例
2017/05/10 Javascript
Vue.js中轻松解决v-for执行出错的三个方案
2017/06/09 Javascript
解析Vue2 dist 目录下各个文件的区别
2017/11/22 Javascript
nodejs调取微信收货地址的方法
2017/12/20 NodeJs
Vue的路由动态重定向和导航守卫实例
2018/03/17 Javascript
原生js滑动轮播封装
2020/07/31 Javascript
创建与框架无关的JavaScript插件
2020/12/01 Javascript
[31:55]完美世界DOTA2联赛循环赛 IO vs GXR BO2第一场 11.04
2020/11/05 DOTA
python自动zip压缩目录的方法
2015/06/28 Python
Python算法输出1-9数组形成的结果为100的所有运算式
2017/11/03 Python
使用tensorflow实现AlexNet
2017/11/20 Python
python turtle库画一个方格和圆实例
2019/06/27 Python
Python3 requests文件下载 期间显示文件信息和下载进度代码实例
2019/08/16 Python
python/golang 删除链表中的元素
2020/09/14 Python
html5跳转小程序wx-open-launch-weapp踩坑
2020/12/02 HTML / CSS
Laura Mercier官网:彩妆大师罗拉玛斯亚的化妆品牌
2018/01/04 全球购物
生物技术专业研究生自荐信
2013/09/22 职场文书
前台接待的工作职责
2013/11/21 职场文书
李开复演讲稿
2014/05/24 职场文书
2014国庆节餐厅促销活动策划方案
2014/09/16 职场文书
鸟的天堂导游词
2015/01/31 职场文书
周一给客户的问候语
2015/11/10 职场文书
解决Python保存文件名太长OSError: [Errno 36] File name too long
2022/05/11 Python