Skip to content

React-Navigation 使用笔记

React-Navigation 之自定义 Header

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

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

参考官方文档:

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

javascript
static navigationOptions = {
  title: 'Home',
}
static navigationOptions = {
  title: 'Home',
}

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

jsx
static navigationOptions = () => (
  {
    header: () => <Header title="首页" showBack={false}></Header>
  }
)
static navigationOptions = () => (
  {
    header: () => <Header title="首页" showBack={false}></Header>
  }
)

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

自定义用法的参数传递:

传递

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

接收

jsx
static navigationOptions = ({navigation}) => (
  {
    header: () => <Header title={navigation.state.params.title}></Header>
  }
)
static navigationOptions = ({navigation}) => (
  {
    header: () => <Header title={navigation.state.params.title}></Header>
  }
)

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

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

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

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

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

第二种,通过 params 传递:

jsx
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>
    }
}
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>
    }
}
jsx
// 在 class 中
componentDidMount() {
    this.props.navigation.setParams({
      onSearchPress: () => this.onSearchPress(),
      navTitle: '首页'
    });
}
// 在 class 中
componentDidMount() {
    this.props.navigation.setParams({
      onSearchPress: () => this.onSearchPress(),
      navTitle: '首页'
    });
}

React-Navigation 之修改 StackNavigator 过渡动画

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

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

在配置中加入

jsx
const AppRouteConfigs = {
  Main: { screen: MainView },
  AMap: { screen: AMap },
  Login: { screen: Login },
};
/**
 * 路由配置
 */
const AppNavigator = StackNavigator(AppRouteConfigs, {
  initialRouteName: "Main",
  headerMode: "float",
  transitionConfig: () => ({
    screenInterpolator: CardStackStyleInterpolator.forHorizontal,
  }),
});
const AppRouteConfigs = {
  Main: { screen: MainView },
  AMap: { screen: AMap },
  Login: { screen: Login },
};
/**
 * 路由配置
 */
const AppNavigator = StackNavigator(AppRouteConfigs, {
  initialRouteName: "Main",
  headerMode: "float",
  transitionConfig: () => ({
    screenInterpolator: CardStackStyleInterpolator.forHorizontal,
  }),
});

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

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

最后编辑时间:

Version 4.0 (framework-1.0.0-rc.20)