I18nManager.forceRTL不会在第一个应用程序加载中应用更改

时间:2018-02-06 08:36:28

标签: reactjs react-native

我有一个由强大的 React-native 创建的应用,我的布局设计为RTL模式。我已经设置了一个强制布局为RTL的选项,但我的选项在安装后的第一个应用程序加载中不起作用。此功能适用于第二次运行。

我在index.js中写了这个选项:

import React, { Component } from 'react';
import { I18nManager } from 'react-native';
import { Provider } from 'react-redux';

I18nManager.forceRTL(true);

class App extends Component {
  render() {
    return (
      <Provider store={store}>
        <PersistGate loading={null} persistor={persistor}>
          <MainStack />
        </PersistGate>
      </Provider>
    );
  }
}

export default App;

5 个答案:

答案 0 :(得分:5)

经过一周的努力,终于找到了使用 Redux&amp; amp;来解决这个问题的逻辑方法。 react-native-restart 插件。我也使用漂亮的启动画面,用户不会为此目的显示重新启动的进度。

让我们深入研究代码:

Redux操作:

export const GET_APP_LAYOUT_DIRECTION = 'GET_APP_LAYOUT_DIRECTION';
export const SET_APP_LAYOUT_DIRECTION = 'SET_APP_LAYOUT_DIRECTION';

export const getAppLayoutDirection = () => ({
  type: GET_APP_LAYOUT_DIRECTION,
});

export const setAppLayoutDirection = direction => ({
  type: SET_APP_LAYOUT_DIRECTION,
  direction
});

Redux Reducer:

import {
    GET_APP_LAYOUT_DIRECTION,
    SET_APP_LAYOUT_DIRECTION,
} from '../actions/app';

const initialState = {
    layout: 'ltr',
};

const reducer = (state = initialState, action) => {
    switch (action.type) {
      case GET_APP_LAYOUT_DIRECTION:
        return {
          ...state,
        };
      case SET_APP_LAYOUT_DIRECTION:
        return {
          ...state,
          layout: action.direction,
        };
      default:
        return state;
    }
};

export default reducer;

主屏幕:

import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import RNRestart from 'react-native-restart'; // Import package from node modules
import { getAppLayoutDirection, setAppLayoutDirection } from '../actions/app';

class Home extends PureComponent {
   constructor(props) {
     super(props);

     this.props.dispatch(getAppLayoutDirection());
     if(this.props.layout === 'ltr'){
       this.props.dispatch(setAppLayoutDirection('rtl'));
       RNRestart.Restart();
     }
  }

  componentDidMount() {
     if(this.props.layout && this.props.layout === 'rtl'){
        SplashScreen.hide();
     }
  }
} 

const mapStateToProps = (state) => {
  const { layout } = state.app;
  return {
    layout
  };
}

export default connect(mapStateToProps)(Home);

答案 1 :(得分:3)

我遇到了同样对我有帮助的问题。 这是一个经过修改的答案,无需使用redux。

首先,您使用I18nManager.isRTL检查当前状态,然后使用react-native-restart强制使用RTRTL。

   constructor(props) {          
      //Force RTL
      if(I18nManager.isRTL != true){
         I18nManager.forceRTL(true);
         RNRestart.Restart();
      }
   }

答案 2 :(得分:3)

我遇到了同样的问题,并通过forceRTL方法在MainApplication.java中调用onCreate解决了这个问题。

...
import com.facebook.react.modules.i18nmanager.I18nUtil;

...
 @Override
  public void onCreate() {
    super.onCreate();
    SoLoader.init(this, /* native exopackage */ false);

    I18nUtil sharedI18nUtilInstance = I18nUtil.getInstance();
    sharedI18nUtilInstance.forceRTL(this,true);
    sharedI18nUtilInstance.allowRTL(this, true);
  }
...

在IOS上,添加AppDelegate.m

...
NSURL *jsCodeLocation; // this probably already exists!
[[RCTI18nUtil sharedInstance] allowRTL:YES];
[[RCTI18nUtil sharedInstance] forceRTL:YES];
...

Source

答案 3 :(得分:0)

确保在iOS上,将所有相关RTL语言环境添加到您的Xcode项目(例如阿拉伯语)旁边。您还应该确保您的.ipa包含每个语言环境的.lproj文件夹。否则,iOS无法使用受支持的语言。

这是React Native项目中的常见问题,您通常不会编写很多Swift / Obj-C代码,而且大多数翻译都是在JavaScript中进行的(除了Info.plist中的某些内容)。 / p>

答案 4 :(得分:0)

那是因为您应该将 I18nManager 与 try and catch 一起使用! 它需要“等待”才能完成他的工作。

try {
    I18nManager.allowRTL(false);
  } catch (e) {
    console.log(e);
  }

像这样使用它,它会起作用。