React Native开发React Native开发经验集Android架构设计

React Navigation的集成及使用

2019-08-01  本文已影响6人  wenny826

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

官方文档

一.简介

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.页面切换
3.React Navigation 生命周期
image.png
图片来源
react-native 生命周期文章内
4.React Navigation 路由传参

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

5.StackNavigatorConfig导航器配置
6.用于导航器内部页面的navigationOptions

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

//创建了一个导航器,里面含有命名为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
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
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
上一篇 下一篇

猜你喜欢

热点阅读