Back

reactnative - 10. 国际化 i18n

发布时间: 2018-12-22 11:43:00

参考:https://github.com/react-native-community/react-native-languages

这里包含了具体的例子 , 见example 文件夹

1. 安装:

yarn add react-native-languages --verbose  ( 用npm可能会报错, windows下)

1.1  安装  i18n-js

yarn add i18n-js --verbose    (注意,我这里使用了yarn 代替npm 还是因为npm install 不行, yarn add)

2. react-native link react-native-languages

对于安卓来说, 上面的命令已经把该干的事情干了。 IOS 日后补上 。

3. 使用。 

3.1  写好各种i18n 的文件, 

// src/translations/en.json
{
  "title": "react-native-languages demo",
  "current": "The current language is \"{{language}}\""
}

3.2 引入这些文件 (src/i18n.js) 这个文件算是一个汇总文件。 它也是要被别的文件引用的

import RNLanguages from 'react-native-languages';
import i18n from 'i18n-js';

import en from './translations/en.json';
import fr from './translations/fr.json';
import de from './translations/de.json';

i18n.locale = RNLanguages.language;
i18n.fallbacks = true;
i18n.translations = { en, fr, de };

export default i18n;

3.3 在实际的代码中: ( src/App.js)

<Text style={styles.title}>{i18n.t('title')}</Text>

import React, { Component } from 'react';
import RNLanguages from 'react-native-languages';
import i18n from './i18n';
import Root from './Root';

export default class App extends Component {
// 貌似下面这些 listener 和 event貌似没用。
  componentWillMount() {
    RNLanguages.addEventListener('change', this._onLanguagesChange);
  }

  componentWillUnmount() {
    RNLanguages.removeEventListener('change', this._onLanguagesChange);
  }

  _onLanguagesChange = ({ language }) => {
    i18n.locale = language;
  };

  render() {
    return (
         <View>    {i18n.t('current', { language: i18n.currentLocale() })}        </View>
    )
  }
}

3.4 上面的代码是根据本机的语言自动识别。 下面是做成 “动态修改语言的”

import RNLanguages from 'react-native-languages';
import i18n from 'i18n-js';
import { AsyncStorage } from "react-native"

import en from '../translations/en.json';
import zh from '../translations/zh.json';

determinLanguage = async () => {
  try{
    global.language = await AsyncStorage.getItem("language")
  }catch(error){
    global.language = "en"
    console.error(error)
  }
  console.info("== language is : " + global.language)
  // i18n.locale = language
}

determinLanguage()

// i18n.locale = RNLanguages.language
// 这里只是一个默认的语言. 具体的语言还是需要靠上面的 global.language 来确定。
// 这里无法通过 async 方法来设置 i18n.locale
// 在后续的所有页面的渲染中,都要使用  i18n.t('title', { locale: global.language})
i18n.fallbacks = true;
i18n.translations = { en, zh };

// 记得这里必须是 locale!
global.t = (key) => {
  return i18n.t(key, { locale: global.language })
}

export default i18n;

然后,在调用的时候, 直接 <Text>{ t('index') } </Text>

修改语言:

import React, {Component} from 'react';
import constants from '../constants'
import {
  Alert,
  StyleSheet,
  Text, View,
  Image,
  Dimensions,
  TouchableOpacity,
  ScrollView } from 'react-native';
import i18n from '../util/i18n'
import Button from 'react-native-button';
import { AsyncStorage } from "react-native"
import RNRestart from "react-native-restart"

export default class ChangeLanguage extends Component {
  constructor(props) {
    super(props);
  }

  change = async (language) => {
    console.info("== changing language to:" + language)
    await AsyncStorage.setItem("language", language)
    RNRestart.Restart()
  }

  render(){
    const {navigation} = this.props;
    return (
      <View style={styles.container}>
        <Button
          onPress={ () => {
            this.change("en")
          }}
          containerStyle={styles.logoutBtnContainer}
          style={styles.logoutBtn}
          >
          English
        </Button>
        <Button
          onPress={ () => {
            this.change("zh")
          }}
          containerStyle={styles.logoutBtnContainer}
          style={styles.logoutBtn}
          >
          简体中文
        </Button>

        <Text style={{color: 'white'}}>{global.language}(global.t): {global.t('index')}
      </View>
  )}
}
)

Back