React-Navigation 使用笔记

# React-Navigation 之自定义 Header

React-Native 的新版本取消了 navigator,使用了新的 React-Navigation 组件。这个组件非常强大。

但是有的时候我们需要自定义 Header,又不想在每个 View 上附带 Header,而是想要实现原生的效果(即 Header 是一个独立的层,和视图无关)。

参考官方文档:

普通用法:在每个StackNavigator管理的视图class中加入static属性

static navigationOptions = {
  title: 'Home',
}
1
2
3

自定义用法:这里的 Header 是一个自定义组件

static navigationOptions = () => (
  {
    header: () => <Header title="首页" showBack={false}></Header>
  }
)
1
2
3
4
5

注意,如果用 Redux 管理了 navigation,那么自定义的 Header 中需要 connect 一下 nav 中的 dispatch 方法。

自定义用法的参数传递:

传递

// 直接用 NavigationActions
NavigationActions.navigate({ routeName: "AMap", params: { title: "地图" } });
// 结合 redux
this.props.dispatch(NavigationActions.navigate({ routeName: "AMap", params: { title: "地图" } }));
1
2
3
4

接收

static navigationOptions = ({navigation}) => (
  {
    header: () => <Header title={navigation.state.params.title}></Header>
  }
)
1
2
3
4
5

解构出 navigation 属性,通过 navigation.state.params 来获取传递的数据。

# React-Navigation 之传递参数到自定义 Header

在 React-Navigation 中,定义 Header 是通过 static 属性来定义的,这样导致 class 中的 this 无法获取。与 this.state 的通信形成了障碍。

解决这个问题的方式有 2 种,第一种是由 redux 控制 Header 的状态和事件,第二种是通过 navigation.state.params 传递。

第一种是一种通用方法,不再阐述。

第二种,通过 params 传递:

static navigationOptions = ({ navigation }) => {
    const { params = {} } = navigation.state;
    return {
      header: () => <Header showBack={false}
        title={params.navTitle}
        rightIcon={<Image style={{ width: 20, height: 20 }} source={searchIcon}></Image>}
        onRightIconPress={params.onSearchPress}>
      </Header>
    }
}
1
2
3
4
5
6
7
8
9
10
// 在 class 中
componentDidMount() {
    this.props.navigation.setParams({
      onSearchPress: () => this.onSearchPress(),
      navTitle: '首页'
    });
}
1
2
3
4
5
6
7

# React-Navigation 之修改 StackNavigator 过渡动画

默认情况下不能修改,修改引入 CardStackStyleInterpolator,这个模块在不同版本的库中位置不同。

import CardStackStyleInterpolator from "react-navigation/src/views/CardStack/CardStackStyleInterpolator";
1

在配置中加入

const AppRouteConfigs = {
  Main: { screen: MainView },
  AMap: { screen: AMap },
  Login: { screen: Login },
};
/**
 * 路由配置
 */
const AppNavigator = StackNavigator(AppRouteConfigs, {
  initialRouteName: "Main",
  headerMode: "float",
  transitionConfig: () => ({
    screenInterpolator: CardStackStyleInterpolator.forHorizontal,
  }),
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

react-navigation 一共提供了 4 种跳转动画:

1、从右向左: forHorizontal; 2、从下向上: forVertical; 3、安卓那种的从下向上: forFadeFromBottomAndroid; 4、无动画: forInitial。