Как заставить приложение React Native сохранять выбранный язык при перезапуске приложения - PullRequest
0 голосов
/ 08 мая 2020

Я хочу, чтобы в моем приложении был экран настроек, чтобы я мог изменить язык из средства выбора. Я хочу, чтобы изменение языка отражалось во всем приложении, и я хочу, чтобы приложение запоминало последний выбранный язык. Ниже приведен мой index. js, который импортирует мой язык пары ключ-значение для en, am или, tg,

index. js

import * as RNLocalize from 'react-native-localize';
import I18n from 'i18n-js';
import memoize from 'lodash.memoize'; 

import en from './en';
import am from './am';
import or from './or';
import tg from './tg';

const locales = RNLocalize.getLocales();
if (Array.isArray(locales)) {
  I18n.locale = locales[0].languageTag;
}

I18n.translations = {
  default: en,
  'en-US': en,
  en,
  am,
  or,
  tg,

};

I18n.fallbacks = true;
export default I18n;

Я хочу изменить язык приложение из моего экрана настроек. где я подготовил сборщик для выбора языка. приведенный ниже мой код экрана настройки.

Экран настроек. js

import I18n from './../i18n/locales';

const width = Dimensions.get('window').width;
const height = Dimensions.get('window').height;

const listLanguage = [
  {key:'en', label:'En'}, {key:'am', label:'Am'} ,{key:'or', label: 'OR'}, {key:'tg', label:'TG'},] 

export default class SettingsScreen extends React.Component {
  constructor(props) {
    super(props);
    this.state = { visible: true ,
                  languageSelected: 'en'
    };
  }

  backToMain() {
    this.props.navigation.navigate('LocationTrackingScreen', {});
  }

  handleBackPress = () => {
    this.props.navigation.navigate('LocationTrackingScreen', {});
    return true;
  };

  hideSpinner() {
    this.setState({ visible: false });
  }

  componentDidMount() {
    BackHandler.addEventListener('hardwareBackPress', this.handleBackPress);
  }

  componentWillUnmount() {
    BackHandler.removeEventListener('hardwareBackPress', this.handleBackPress);
  }

  onChangeLanguage(languageSelected){
    this.setState({
      languageSelected
    })
       I18n.locale = languageSelected 
  }

  render() {
    const {languageSelected} = this.state

    return (
      <SafeAreaView style={styles.container}>

      <View style={styles.containerDropdown}>
              <DropdownLanguage language={languageSelected} onChangeLanguage={this.onChangeLanguage.bind(this)}></DropdownLanguage>

      </View>
    </SafeAreaView>
    );
  }
}
class DropdownLanguage extends React.Component {
  constructor(props) {
    super(props)  
  }

  render() {
    return (
<View style={styles.dropdown}>
              <Picker
                mode="dropdown"
                iosHeader={''} 
                style={{ width: width,height:70,}}
                selectedValue={this.props.language}
                onValueChange={this.props.onChangeLanguage.bind(this)}
              >
                {listLanguage.map((languageItem, i) => {
                    return <Picker.Item key={i} value={languageItem.key} label= {languageItem.label} />
                })}
              </Picker>

            </View>
)
  }
}

Ответы [ 2 ]

0 голосов
/ 08 мая 2020

просто создайте файл с именем TranslationManager. js и вставьте в него следующий код

import * as RNLocalize from 'react-native-localize';
import i18n from 'i18n-js';
import memoize from 'lodash.memoize';
import {I18nManager, AsyncStorage} from 'react-native';

const translationGetters = {
  // lazy requires (metro bundler does not support symlinks)
  en: () => require('./Languages/en.json'),
  ar: () => require('./Languages/ar.json'),
};
export const translate = memoize((key, config) => i18n.t(key, config));
// export const translate = text => {
//   console.log(i18n.t(text));
// };

export const setI18nConfig = lang => {
  // fallback if no available language fits
  const fallback = {languageTag: 'en', isRTL: false};

  const {isRTL, languageTag} =
    RNLocalize.findBestAvailableLanguage(Object.keys(translationGetters)) ||
    fallback;

  // clear translation cache
  translate.cache.clear();
  // update layout directio
  // set i18n-js config
  I18nManager.forceRTL(false);
  i18n.translations = {['en']: translationGetters.en()};
  i18n.locale = 'en';

  if (lang) {
    i18n.translations = {[lang]: translationGetters[lang]()};
    i18n.locale = lang;
  } else {
    i18n.translations = {['en']: translationGetters.en()};
    i18n.locale = 'en';
  }
};

export const changeLanguage = async lang => {
  setI18nConfig(lang);
  AsyncStorage.setItem('language', lang);
};

export const isRTL = () => {
  return translate('lang') === 'ar' ? true : false;
};

Нет, у вас есть отдельный класс для изменения языка приложения. Просто импортируйте эту функцию changeLanguage куда угодно и измените язык следующим образом:

import {changeLanguage} from '../../Translations/TranslationManager';
let language = await AsyncStorage.getItem('language');
changeLanguage(language);

Вы можете показать переведенный текст следующим образом:

import {translate} from '../../Translations/TranslationManager';
<Text>translate('ForumScreen.title')</Text>

Надеюсь, это поможет вам сейчас и в будущем.

0 голосов
/ 08 мая 2020

Вы можете сохранить выбранный язык в AsyncStorage, и когда пользователь откроет приложение, вы можете проверить последний выбранный язык из AsyncStorage и установить его в качестве языка приложения. Это пример того, как я это делаю в своих проектах:

При изменении языка установите язык в AsyncStorage следующим образом

    export const changeLanguage = async lang => {
         setI18nConfig(lang);
         AsyncStorage.setItem('language', lang);
     };

И когда пользователь повторно откроет приложение, просто получите язык на первом экране и установите его в качестве языка приложения, например:

let language = await AsyncStorage.getItem('language');
changeLanguage(language);

Надеюсь, это вам поможет

...