陈桥驿站 陈桥驿站

ReactNative react-navigation3.x.x

--> React Native 阅读 ( 258 ) 文章转载请注明来源!

前言

截止博客发表,react-navigation最新版本是3.1.3
<font color="red">注意:现在百度到所有关于react-navigation的资料在3.x.x版本上都不好使,尤其是现在博客有一个不好的现象就是抄袭。所以一定要懂得自己去官方的文档查API。</font>

推荐网址

环境

<font color="red">React Native 0.55.3 + React Navigation 3.1.3</font>

使用

install react-navigation

MacBookPro:Scholar www.tomcat7.cn$ npm install react-navigation
npm WARN rm not removing /Users/mac/Scholar/node_modules/.bin/sane as it wasn't installed by /Users/mac/Scholar/node_modules/sane
npm WARN rm not removing /Users/mac/Scholar/node_modules/.bin/json5 as it wasn't installed by /Users/mac/Scholar/node_modules/json5
npm WARN rm not removing /Users/mac/Scholar/node_modules/.bin/jsesc as it wasn't installed by /Users/mac/Scholar/node_modules/jsesc
npm WARN rm not removing /Users/mac/Scholar/node_modules/.bin/jest as it wasn't installed by /Users/mac/Scholar/node_modules/jest-cli
npm WARN rm not removing /Users/mac/Scholar/node_modules/.bin/esparse as it wasn't installed by /Users/mac/Scholar/node_modules/esprima
npm WARN rm not removing /Users/mac/Scholar/node_modules/.bin/esvalidate as it wasn't installed by /Users/mac/Scholar/node_modules/esprima

> fsevents@1.2.7 install /Users/mac/Scholar/node_modules/fsevents
> node install

node-pre-gyp WARN Using request for node-pre-gyp https download 
[fsevents] Success: "/Users/mac/Scholar/node_modules/fsevents/lib/binding/Release/node-v64-darwin-x64/fse.node" is installed via remote
npm notice created a lockfile as package-lock.json. You should commit this file.
npm WARN eslint-plugin-react-native@3.6.0 requires a peer of eslint@^3.17.0 || ^4 || ^5 but none is installed. You must install peer dependencies yourself.

+ react-navigation@3.1.3
added 70 packages from 24 contributors, removed 55 packages, updated 867 packages and audited 85733 packages in 68.375s
found 2 vulnerabilities (1 low, 1 high)
  run `npm audit fix` to fix them, or `npm audit` for details

install react-native-gesture-handler

MacBookPro:Scholar www.tomcat7.cn$ npm install react-native-gesture-handler
npm WARN eslint-plugin-react-native@3.6.0 requires a peer of eslint@^3.17.0 || ^4 || ^5 but none is installed. You must install peer dependencies yourself.

+ react-native-gesture-handler@1.0.15
updated 5 packages and audited 85742 packages in 18.012s
found 2 vulnerabilities (1 low, 1 high)
  run `npm audit fix` to fix them, or `npm audit` for details

link

MacBookPro:Scholar www.tomcat7.cn$ react-native link
Scanning folders for symlinks in /Users/mac/Scholar/node_modules (16ms)
rnpm-install info Linking react-native-gesture-handler ios dependency 
rnpm-install info Platform 'ios' module react-native-gesture-handler has been successfully linked 
rnpm-install info Linking react-native-gesture-handler android dependency 
rnpm-install info Platform 'android' module react-native-gesture-handler has been successfully linked

import

import {createStackNavigator, createAppContainer} from 'react-navigation';

react-navigation

<font color="red">注意:网上基本上现在能搜到的都是错误的,react-navigation库更新比较快,所以请直接参考官方的英文文档编写测试Demo。</font>

第一版错误写法

类似于如下形式这是1.x版本的写法。

import {StackNavigator} from 'react-navigator' ... ....
do Something ... ...

第二版错误写法

import {createStackNavigator} from 'react-navigator' ... ...
do Something ... ...
render(){
    return (<Pages />);
}

最新版本正确写法

const Pages = createStackNavigator({
    Profile: {
      screen: Home,
      navigationOptions: ({navigate}) => ({
        header: null
      }),
    }
})

export default createAppContainer(Pages);

this.props.navigation报错

<font color="red">Cannot read property 'navigate' of undefined.</font>

Main.js

import { withNavigation } from 'react-navigation';
export default withNavigation(Main);

API

createNavigator


id: stack-navigator
title: createStackNavigator

sidebar_label: createStackNavigator

Provides a way for your app to transition between screens where each new screen is placed on top of a stack.

By default the stack navigator is configured to have the familiar iOS and Android look & feel: new screens slide in from the right on iOS, fade in from the bottom on Android. On iOS the stack navigator can also be configured to a modal style where screens slide in from the bottom.

API Definition

createStackNavigator(RouteConfigs, StackNavigatorConfig);

RouteConfigs

The route configs object is a mapping from route name to a route config, which tells the navigator what to present for that route.

createStackNavigator({
  // For each screen that you can navigate to, create a new entry like this:
  Profile: {
    // `ProfileScreen` is a React component that will be the main content of the screen.
    screen: ProfileScreen,
    // When `ProfileScreen` is loaded by the StackNavigator, it will be given a `navigation` prop.

    // Optional: When deep linking or using react-navigation in a web app, this path is used:
    path: 'people/:name',
    // The action and route params are extracted from the path.

    // Optional: Override the `navigationOptions` for the screen
    navigationOptions: ({ navigation }) => ({
      title: `${navigation.state.params.name}'s Profile'`,
    }),
  },

  ...MyOtherRoutes,
});

StackNavigatorConfig

Options for the router:

  • initialRouteName - Sets the default screen of the stack. Must match one of the keys in route configs.
  • initialRouteParams - The params for the initial route
  • initialRouteKey - Optional identifier of the initial route
  • defaultNavigationOptions - Default navigation options to use for screens
  • paths - A mapping of overrides for the paths set in the route configs

Visual options:

  • mode - Defines the style for rendering and transitions:

    • card - Use the standard iOS and Android screen transitions. This is the default.
    • modal - Make the screens slide in from the bottom which is a common iOS pattern. Only works on iOS, has no effect on Android.
  • headerMode - Specifies how the header should be rendered:

    • float - Render a single header that stays at the top and animates as screens are changed. This is a common pattern on iOS.
    • screen - Each screen has a header attached to it and the header fades in and out together with the screen. This is a common pattern on Android.
    • none - No header will be rendered.
  • headerBackTitleVisible - A reasonable default is supplied for whether the back button title should be visible or not, but if you want to override that you can use true or false in this option.
  • headerTransitionPreset - Specifies how the header should transition from one screen to another when headerMode: float is enabled.

    • fade-in-place - Header components cross-fade without moving, similar to the Twitter, Instagram, and Facebook app for iOS. This is the default value.
    • uikit - An approximation of the default behavior for iOS.
  • headerLayoutPreset - Specifies how to lay out the header components.

    • left - Anchor the title to the left, near the back button or other left component. This is the default on Android. When used on iOS, the header back title is hidden. Content from the left component will overflow underneath the title, if you need to adjust this you can use headerLeftContainerStyle and headerTitleContainerStyle. Additionally, this alignment is incompatible with headerTransitionPreset: 'uikit'.
    • center - Center the title, this is the default on iOS.
  • cardStyle - Use this prop to override or extend the default style for an individual card in stack.
  • cardShadowEnabled - Use this prop to have visible shadows during transitions. Defaults to true
  • cardOverlayEnabled - Use this prop to have visible stack card overlays during transitions. Defaults to false.
  • transitionConfig - Function to return an object that is merged with the default screen transitions (take a look at TransitionConfig in [type definitions](
    https://github.com/react-navigation/react-navigation/blob/master/flow/react-navigation.js)). Provided function will be passed the following arguments:

    • transitionProps - Transition props for the new screen.
    • prevTransitionProps - Transitions props for the old screen.
    • isModal - Boolean specifying if screen is modal.
  • onTransitionStart - Function to be invoked when the card transition animation is about to start.
  • onTransitionEnd - Function to be invoked once the card transition animation completes.
  • transparentCard - Experimental - Prop to keep all cards in the stack visible and add a transparent background instead of a white one. This is useful to implement things like modal dialogs where the previous scene should still be visible underneath the current one.

navigationOptions for screens inside of the navigator

title

String that can be used as a fallback for headerTitle. Additionally, will be used as a fallback for tabBarLabel (if nested in a TabNavigator) or drawerLabel (if nested in a DrawerNavigator).

header

React Element or a function that given HeaderProps returns a React Element, to display as a header. Setting to null hides header.

headerTitle

String, React Element or React Component used by the header. Defaults to scene title. When a component is used, it receives allowFontScaling, style and children props. The title string is passed in children.

headerTitleAllowFontScaling

Whether header title font should scale to respect Text Size accessibility settings. Defaults to true.

headerBackImage

React Element or Component to display custom image in header's back button. When a component is used, it receives a number of props when rendered (tintColor, title). Defaults to Image component with react-navigation/views/assets/back-icon.png back image source, which is the default back icon image for the platform (a chevron on iOS and an arrow on Android).

headerBackTitle

Title string used by the back button on iOS, or null to disable label. Defaults to the previous scene's headerTitle. headerBackTitle has to be defined in the origin screen, not in the destination screen. For instance, when you have a transition A to B and you want to disable the headerBackTitle on B:

StackNavigator({
  A: {
    screen: AScreen,
    navigationOptions: () => ({
      title: `A`,
      headerBackTitle: null
    }),
  },
  B: {
    screen: BScreen,
    navigationOptions: () => ({
      title: `B`,
    }),
  }
});

headerTruncatedBackTitle

Title string used by the back button when headerBackTitle doesn't fit on the screen. "Back" by default. headerTruncatedBackTitle has to be defined in the origin screen, not in the destination screen. For instance, when you have a transition A to B and you want to truncate the label on B:

StackNavigator({
  A: {
    screen: AScreen,
    navigationOptions: () => ({
      title: `A`,
      headerBackTitle: 'A much too long text for back button from B to A',
      headerTruncatedBackTitle: `to A`
    }),
  },
  B: {
    screen: BScreen,
    navigationOptions: () => ({
      title: `B`,
    }),
  }
});

headerRight

React Element to display on the right side of the header.

headerLeft

React Element or Component to display on the left side of the header. When a component is used, it receives a number of props when rendered (onPress, title, titleStyle and more - check Header.js for the complete list).

headerStyle

Style object for the header

headerForceInset

Allows to pass forceInset object to internal SafeAreaView used in the header.

headerTitleStyle

Style object for the title component

headerBackTitleStyle

Style object for the back title

headerLeftContainerStyle

Customize the style for the container of the headerLeft component, for example to add padding.

headerRightContainerStyle

Customize the style for the container of the headerRight component, for example to add padding.

headerTitleContainerStyle

Customize the style for the container of the headerTitle component, for example to add padding.

By default, headerTitleContainerStyle is with an absolute position style and offsets both left and right. This may lead to white space or overlap between headerLeft and headerTitle if a customized headerLeft is used. It can be solved by adjusting left and right style in headerTitleContainerStyle and marginHorizontal in headerTitleStyle.

headerTintColor

Tint color for the header

headerPressColorAndroid

Color for material ripple (Android >= 5.0 only)

headerTransparent

Defaults to false. If true, the header will not have a background unless you explicitly provide it with headerStyle or headerBackground.

headerBackground

Use this with headerTransparent to provide a component to render in the background of the header. You can use this with a blur view, for example, to create a translucent header.

headerBackgroundTransitionPreset

One of toggle | fade | translate; lets you choose how to transition your custom headerBackground components between screens.

gesturesEnabled

Whether you can use gestures to dismiss this screen. Defaults to true on iOS, false on Android.

gestureResponseDistance

Object to override the distance of touch start from the edge of the screen to recognize gestures. It takes the following properties:

  • horizontal - number - Distance for horizontal direction. Defaults to 25.
  • vertical - number - Distance for vertical direction. Defaults to 135.

gestureDirection

String to override the direction for dismiss gesture. default for normal behaviour or inverted for right-to-left swipes.

params

You can provide default params inside route definitions:

const Store = createStackNavigator({
  Playstation: { screen: ProductScreen, params: { product: 'Playstation' } },
  Xbox: { screen: ProductScreen, params: { product: 'Xbox' } },
});

Navigator Props

The navigator component created by createStackNavigator(...) takes the following props:

  • screenProps - Pass down extra options to child screens, for example:
const SomeStack = createStackNavigator({
  // config
});

<SomeStack
  screenProps={/* this prop will get passed to the screen components as this.props.screenProps */}
/>

Examples

See the examples SimpleStack.js and ModalStack.js which you can run locally as part of the NavigationPlayground app.

You can view these examples directly on your phone by visiting our expo demo.

Modal StackNavigator with Custom Screen Transitions

const ModalNavigator = createStackNavigator(
  {
    Main: { screen: Main },
    Login: { screen: Login },
  },
  {
    headerMode: 'none',
    mode: 'modal',
    defaultNavigationOptions: {
      gesturesEnabled: false,
    },
    transitionConfig: () => ({
      transitionSpec: {
        duration: 300,
        easing: Easing.out(Easing.poly(4)),
        timing: Animated.timing,
      },
      screenInterpolator: sceneProps => {
        const { layout, position, scene } = sceneProps;
        const { index } = scene;

        const height = layout.initHeight;
        const translateY = position.interpolate({
          inputRange: [index - 1, index, index + 1],
          outputRange: [height, 0, 0],
        });

        const opacity = position.interpolate({
          inputRange: [index - 1, index - 0.99, index],
          outputRange: [0, 1, 1],
        });

        return { opacity, transform: [{ translateY }] };
      },
    }),
  }
);

Header transitions can also be configured using headerLeftInterpolator, headerTitleInterpolator and headerRightInterpolator fields under transitionConfig.

Specifying the transition mode for a stack's screens explicitly

We can't set the StackNavigatorConfig's mode dynamically. Instead we are going to use a custom transitionConfig to render the specfific transition we want - modal or card - on a screen by screen basis.

import { createStackNavigator, StackViewTransitionConfigs } from 'react-navigation';

/* The screens you add to IOS_MODAL_ROUTES will have the modal transition.  */
const IOS_MODAL_ROUTES = ['OptionsScreen'];

let dynamicModalTransition = (transitionProps, prevTransitionProps) => {
  const isModal = IOS_MODAL_ROUTES.some(
    screenName =>
      screenName === transitionProps.scene.route.routeName ||
      (prevTransitionProps && screenName === prevTransitionProps.scene.route.routeName)
  )
  return StackViewTransitionConfigs.defaultTransitionConfig(
    transitionProps,
    prevTransitionProps,
    isModal
  );
};

const HomeStack = createStackNavigator(
  { DetailScreen, HomeScreen, OptionsScreen },
  { initialRouteName: 'HomeScreen', transitionConfig: dynamicModalTransition }
);

withNavigation


id: with-navigation
title: withNavigation

sidebar_label: withNavigation

withNavigation is a higher order component which passes the navigation prop into a wrapped component. It's useful when you cannot pass the navigation prop into the component directly, or don't want to pass it in case of a deeply nested child.

  • withNavigation(Component) returns a Component.

Example

import React from 'react';
import { Button } from 'react-native';
import { withNavigation } from 'react-navigation';

class MyBackButton extends React.Component {
  render() {
    return <Button title="Back" onPress={() => { this.props.navigation.goBack() }} />;
  }
}

// withNavigation returns a component that wraps MyBackButton and passes in the
// navigation prop
export default withNavigation(MyBackButton);

Notes

  • If you wish to use the ref prop on the wrapped component, you must pass the onRef prop instead. For example,
// MyBackButton.ts
export default withNavigation(MyBackButton);

// MyNavBar.ts
<MyBackButton onRef={(elem) => this.backButton = elem} />

本文基于《署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0)》许可协议授权
文章链接:http://www.cctv3.net/archives/rnNavigation.html (转载时请注明本文出处及文章链接)

React Native
发表新评论
雷姆
拉姆