使用React Navigation

时间:2018-05-11 13:17:08

标签: react-native react-navigation

我需要在我正在处理的React Native应用中实现平板电脑支持。我们决定使用UISplitViewController对我们来说最有意义,但React Navigation(https://reactnavigation.org)对它没有任何支持。

我尝试通过在视图中并排放置2个导航器并修改其getStateForAction以在详细信息视图中打开某些屏幕,以直接的方式解决此问题:

export interface Props {
  MasterNavigator: NavigationContainer;
  DetailNavigator: NavigationContainer;
  detailRouteNames: string[];
}

export class MasterDetailView extends React.Component<Props> {
  masterNavigator: any;
  detailNavigator: any;

  componentDidMount() {
    const { MasterNavigator, DetailNavigator, detailRouteNames } = this.props;
    const defaultMasterGetStateForAction = MasterNavigator.router.getStateForAction;

    MasterNavigator.router.getStateForAction = (action: any, state: any) => {
      if (action.type === NavigationActions.NAVIGATE && detailRouteNames.indexOf(action.routeName) !== -1) {
        action.params.isRootScreen = true;
        this.detailNavigator.dispatch(NavigationActions.reset({ index: 0, actions: [action] }));

        return state;
      }

      return defaultMasterGetStateForAction(action, state);
    };

    const defaultDetailGetStateForAction = DetailNavigator.router.getStateForAction;

    DetailNavigator.router.getStateForAction = (action: any, state: any) => {
      if (action.type === NavigationActions.BACK && state.routes.length === 1) {
        this.masterNavigator.dispatch(NavigationActions.back());
        return null;
      }

      return defaultDetailGetStateForAction(action, state);
    };
  }

  render() {
    const { MasterNavigator, DetailNavigator } = this.props;

    return (
      <View style={styles.view}>
        <View style={styles.masterContainer}>
          <MasterNavigator ref={(mn: any) => this.masterNavigator = mn}/>
        </View>
        <View style={styles.divider}/>
        <View style={styles.detailContainer}>
          <DetailNavigator ref={(dn: any) => this.detailNavigator = dn}/>
        </View>
      </View>
    );
  }
}

主导航器是TabNavigator,每个标签中都有StackNavigator个,详情导航器为StackNavigator。以下是它的外观: result

这种方法很有效,但Android上的后退按钮行为不正确。我希望它在详细导航器中导航,然后在主导航器中导航。可以使它与几个黑客一起工作,但是后来使用后退按钮从应用程序导航回来是不可能的(出于某种原因,当我点击它时没有任何反应)。我可以通过覆盖后退按钮的行为并将操作调度回主/详细导航器或关闭应用程序来尝试解决此问题,但是当将操作分派给导航器时,无法知道它是否响应(特别是使用主导航器,这是一个TabNavigator),所以好像我被卡住了。

以这种方式使用导航器时是否有一些特殊注意事项? React Navigation是否适用于此用例?如果没有,在React Native应用程序中模拟UISplitViewController的其他方法是什么?

1 个答案:

答案 0 :(得分:0)

后退按钮行为不正确的问题是我的错。其中一个屏幕有一个后退按钮处理程序,它始终返回true,因此消耗所有后退按钮(呃!)。我修复了这个并将以下后退按钮处理程序添加到MasterDetailView

private onPressBack = (): boolean => {
    const action = NavigationActions.back();
    return this.detailNavigator.dispatch(action) || this.masterNavigator.dispatch(action);
};

是的,有一种方法可以确定导航器是否消耗了一个动作:navigator.dispatch(action)如果事件被消耗则返回true,否则返回false

修复了后退按钮的问题后,此设置可以很好地模拟UISplitViewController