React Navigation的集成及使用

作者: wenny826 | 来源:发表于2019-08-01 09:46 被阅读6次

一.简介
二.安装集成
三.基本用法及常用属性
四.常用几种导航器的简单示例及混合使用

官方文档

一.简介

React Navigation 为React native提供了一个类似web浏览器一样的内置历史堆栈,React Navigation 的 stack navigator 为应用提供了一种在屏幕之间切换并管理导航历史记录的方式。当用户与它进行交互时,应用程序会从导航堆栈中新增和删除页面,这会导致用户看到不同的页面。除此之外,还提供了在堆栈中的路由之间切换的手势和动画。

二.安装集成

1.在react native项目中安装react-navigation

$ yarn add react-navigation
# or with npm
# npm install react-navigation

2.安装react-native-gesture-handler

$ yarn add react-native-gesture-handler
# or with npm
# npm install react-native-gesture-handler

3.进行关联

$ react-native link react-native-gesture-handler

在Android中,关联后会自动如下添加代码。
3.1 app的build.gridle

    implementation project(':react-native-gesture-handler')

3.2 继承了ReactApplicationMainApplication

image.png
当出现关联失败,项目报红时,注意检查以上代码是否被添加,没有可手动添加。
4.在对应的继承了ReactActivityactivity添加以下代码
image.png

注意:进行关联的过程中可能会出现as报错,关联失败,可Rebuild项目,或者重新link。

$ react-native unlink react-native-gesture-handler //取消关联
$ react-native link react-native-gesture-handler //重新关联

三.基本用法及常用属性

1.创建导航器

createStackNavigator为示例

const taskNavigator = createStackNavigator({
    test1:TestScreen1,
    test2:TestScreen2
})

createStackNavigator是一个返回 React 组件的方法,因此我们可以直接从App.js中导出它以用作我们应用程序的根组件
App.js

const AppContainer = createAppContainer(taskNavigator);

export default class App extends Component {
  render() {
    return <AppContainer />;
  }
}

2.页面切换
  • this.props.navigation.navigate('test1'):首先尝试查找具有该名称的现有路由, 并且只有在堆栈上没有一个新路由时才会推送该路由。
  • this.props.navigation.push('test1'): 向导航堆栈中添加新路由
  • this.props.navigation.goBack(): 返回上一个页面
  • this.props.navigation.popToTop(): 返回堆栈中的第一个页面
3.React Navigation 生命周期
image.png
图片来源
react-native 生命周期文章内
4.React Navigation 路由传参

navigation.navigate('routeName',{paramName:paramValue,...}):传递参数
navigation.getParam(paramName,defaultValue):获取参数

5.StackNavigatorConfig导航器配置
  • initialRouteName: 设置 stack navigator 的默认页面, 必须是路由配置中的某一个
  • initialRouteParams: 初始路由的参数
  • initialRouteKey: 初始路由的可选标识符
  • paths: 覆盖路由配置中设置的路径的映射
  • mode: 定义渲染和转换的样式,card使用标准的 iOS 和 Android 屏幕转换, 这是默认设置。modal页面从屏幕底部滑入,这是iOS的常用模式, 只在 iOS 上生效,在 Android 上无效
  • navigationOptions: 导航器本身的导航选项,用于配置父导航器
6.用于导航器内部页面的navigationOptions
  • title:标题
  • header:返回一个 React 元素的函数,将作为一个标题来显示。 设为 null ,则隐藏标题。
  • headerTitle:Header 使用的字符串,React 元素或React组件。 默认是页面的 title 当一个组件被使用时,它会接受 allowFontScaling、 style 和 children 这几个 props。 标题字符串在children中传递。
  • headerTitleAllowFontScaling:AllowFontScaling -无论标签字体是否应缩放以尊重文字大小可访问性设置, 默认值都是 true。
  • headerBackAllowFontScaling:后退按钮标题字体是否应缩放以符合文本大小辅助功能设置。默认为false。
  • headerBackImage:自定义后退按钮显示图片
  • headerBackTitle:Ios 上的后退按钮使用的标题字符串
  • headerRight:在标题栏右侧展示的 React 组件。
  • headerLeft:在标题栏左侧展示的 React 元素或组件
  • headerStyle:标题的样式对象
  • params:在路由定义内提供默认参数

四.常用几种导航器的简单示例及混合使用

  • createStackNavigator 最常见的导航器, 一次渲染一个页面,并支持页面切换, 当我们打开一个新的页面时,该页面会被置于堆栈的顶层。
    示例:
//创建了一个导航器,里面含有命名为test1,test2的两个Component组件
const taskNavigator = createStackNavigator({
    test1:TestScreen1,
    test2:TestScreen2
})

const AppContainer = createAppContainer(taskNavigator);

export default class App extends Component {
  render() {
    return <AppContainer />;
  }
}

TestScreen1

import React, {Component} from 'react';
import {Platform, StyleSheet, Text, View,Button} from 'react-native';

export default class TestScreen1 extends Component {
    static navigationOptions = {
      title: '第一个界面',
      headerLayoutPreset: "center",
      headerTitleStyle: {
        fontWeight: 'normal',
        fontSize: 16,
        flex: 1,
        textAlign: 'center'
      },
      headerStyle: {
        backgroundColor: 'white',
        elevation: 5,
      },
    };
      render() {
        return (
          <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
            <Text>第一个界面!</Text>
            <Button onPress = { () =>{
                this.props.navigation.navigate('test2')
            }}
            title = "进入第二个界面"/>
          </View>
        );
      }
    }

TestScreen2

export default class TestScreen2 extends Component {
    static navigationOptions = {
      title: '第二个界面',
      headerTitleStyle: {
        fontWeight: 'normal',
        fontSize: 16,
        flex: 1,
        textAlign: 'center',
      },
      headerStyle: {
        backgroundColor: 'white',
        elevation: 5,
      },
      headerRight: <View />
    };
      render() {
        return (
          <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
            <Text>第二个界面!</Text>
          </View>
        );
      }
    }
20190727_152847.gif
  • createBottomTabNavigator 渲染一个 tab bar,让用户可以在多个页面之间切换。
    示例,本示例中运用了两种导航器的结合,BottomTabNavigator的每一个item都是一个StackNavigator
    App.js
const TabNavigator = createBottomTabNavigator({
  "首页" : {
    screen : createStackNavigator({
      screen:HomeScreen,
    }),
    navigationOptions :{
      tabBarIcon :({ focused, tintColor }) =>{
        if(focused) {
          return <Image source = {require ('./icon/7_home_yes.png')} style = {{width: 30 , height : 30}}/>
        } else{
          return <Image source = {require ('./icon/7_home_no.png')} style = {{width: 30 , height : 30}}></Image>
        }
      }
    },
  },
  "发现":{
    screen : createStackNavigator({
      screen:FindScreen,
    }),
    navigationOptions :{
      tabBarIcon :({ focused, tintColor }) =>{
        if(focused) {
          return <Image source = {require ('./icon/7_find_yes.png')} style = {{width: 30 , height : 30}}></Image>
        } else{
          return <Image source = {require ('./icon/7_find_no.png')} style = {{width: 30 , height : 30}}></Image>
        }
      },
    }
  },
  "我的":{
    screen : createStackNavigator({
      screen:MeScreen,
    }),
    navigationOptions :{
      tabBarIcon :({ focused, tintColor }) =>{
        if(focused) {
          return <Image source = {require ('./icon/7_find_yes.png')} style = {{width: 30 , height : 30}}></Image>
        } else{
          return <Image source = {require ('./icon/7_find_no.png')} style = {{width: 30 , height : 30}}></Image>
        }
      },
    }
  },
},{
  initialRouteName: '首页',
  tabBarOptions:{
      backBehavior:"none",
      inactiveTintColor:"#cbd0dc",
      activeTintColor :"#007aff", 
      showIcon: true,
    },
},)
const AppContainer = createAppContainer(TabNavigator);

export default class App extends Component {
  render() {
    return <AppContainer />;
  }
}
20190727_171912.gif
  • createSwitchNavigator一次只显示一个页面。 默认情况下,它不处理返回操作,并在你切换时将路由重置为默认状态
    将createStackNavigator的示例中的createStackNavigator改成createSwitchNavigator
const taskNavigator = createSwitchNavigator({
    test1:TestScreen1,
    test2:TestScreen2
})
const AppContainer = createAppContainer(taskNavigator);

export default class App extends Component {
  render() {
    return <AppContainer />;
  }

效果变成如下:

20190727_180030.gif
第二个界面的返回键没有了,并且按下返回键时不会回到第一个界面,而是直接回退到进入taskNavigator栈之前的页面
  • 打开侧边栏:navigation.openDrawer()
  • 关闭侧边栏:navigation.closeDrawer()
  • 切换侧边栏:navigation.toggleDrawer()

示例:
本示例将StackNavigator,BottomTabNavigator,DrawerNavigator三种导航器结合使用

createDrawerNavigator

const drawerNavigator = createDrawerNavigator({
  home: TabNavigator,
  test1: taskNavigator,
  test3: {
    screen: TestScreen3,
    navigationOptions: {
      drawerLabel: 'test3',
      drawerIcon: ({ focused, tintColor }) => {
        if (focused) {
          return <Image source={require('./icon/7_find_yes.png')} style={{ width: 30, height: 30 }}></Image>
        } else {
          return <Image source={require('./icon/7_find_no.png')} style={{ width: 30, height: 30 }}></Image>
        }
      }
    }
  },
  test4: TestScreen4
}, {
    drawerWidth: 200,
    drawerPosition: "left",
    initialRouteName: "home",
    contentOptions: {
      activeTintColor: "red",
      inactiveTintColor: "blue"
    },
    contentComponent: (props) => (
      <ScrollView>
        <SafeAreaView style={styles.container} forceInset={{ top: 'always', horizontal: 'never' }}>
          <Text >top</Text>
          <DrawerItems {...props} />
          <Text >bottom</Text>
        </SafeAreaView>
      </ScrollView>
    )
  })

home为上面creatBottomTabNavigator示例;
test1为上面的createStackNavigator示例;
给test3菜单栏添加了一个icon;
自定义了一个contentComponent,抽屉的默认组件是可滚动的,只包含 RouteConfig 中路由的链接。现给抽屉添加了一个顶部text和底部text;
contentOptions中设置了DrawerItems的选中和未选中颜色
效果图:

20190731_163122.gif

相关文章

网友评论

    本文标题:React Navigation的集成及使用

    本文链接:https://www.haomeiwen.com/subject/acefrctx.html