RN入门基础12:react-navigation详细讲解

目录

一、介绍

二、代码及使用

1、StackNavigator: 普通页面跳,可传递参数

2、TabNavigator:   类似底部导航栏,用来在同一屏切换不同页面

3、DrawerNavigator:侧滑菜单导航栏,用于轻松设置带抽屉的屏幕

4、属性介绍


一、介绍

RN中文网推荐用react-navigation替代navigator作为新的导航库,从RN 0.43版本开始,官方已经停止维护Navigator了。

首先通过命令安装
npm install react-navigation --save

// 如果安装了yarn 也可以使用以下命令
yarn add react-navigation

该库包含三类组件:
(1)StackNavigator: 普通页面跳,可传递参数
(2)TabNavigator:   类似底部导航栏,用来在同一屏切换不同页面
(3)DrawerNavigator:侧滑菜单导航栏,用于轻松设置带抽屉的屏幕

安装之后导入项目使用即可,如使用StackNavigator
import {StackNavigator} from 'react-navigation';

二、代码及使用

新建项目:myprojectname

1、StackNavigator: 普通页面跳,可传递参数

1.1、首先要在App.js中定义一个StackNavigator对象,创建基本导航栈

const App = StackNavigator({
    // 这个名字任意
    HomeScreen:{
        screen:HomeScreen
    }, // 默认会进入第一个路由视图中,必须要有HomeScreen这个组件
    SecondScreen:{screen:SecondScreen}
});
export default App;

1.2、之后创建相关页面

在根目录下,新建mypages文件夹,添加两个jS文件,HomeScreen.js和SecondScreen.js

HomeScreen.js内容如下

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

export default class HomeScreen extends Component {
    static navigationOptions = ({ navigation }) => {
        return {
            header: () => null, // 隐藏头部
        }
    }

    render() {
        const { navigate } = this.props.navigation;
        return (
            <View>
                <Text style={{fontSize: 32}}>我是主屏</Text>
            </View>
        )
    }
}

StackNavigator()返回一个组件,所以可以直接通过export导出,目前只有一个空的导航,和中间的文字。

注意:在ReactNative中,在App.js中export的组件是整个App的入口(或者叫根组件),通常不会直接导出一个'导航栈'组件,而是用另外一个组件渲染'导航栈'组件。修改App.js如下:

//1.创建StackNavigator导航栏
const App = StackNavigator({
    // 这个名字任意
    HomeScreen:{
        screen:HomeScreen
    }, // 默认会进入第一个路由视图中,必须要有HomeScreen这个组件
    SecondScreen:{screen:SecondScreen}
});
//2.渲染导航栏
export default class myprojectname extends Component  {
    static navigationOptions = ({ navigation }) => {
        return {
            header: () => null, // 隐藏头部
        }
    }

    render() {
        return (
            <App/>
        )
    }
}

1.3、添加第二屏

在SecondScreen内容如下

import React, { Component } from 'react';
import { View, Text } from 'react-native';
import { StackNavigator } from 'react-navigation';
import HomeScreen from './HomeScreen'

export default class SecondScreen extends Component {
    static navigationOptions = ({ navigation }) => {
        return {
            header: ()=>  <Text style={{fontSize: 32}}>我是第二屏</Text>
        }
    }
    render() {
        return (
            <View>

                <Text>SecondScreen</Text>
            </View>
        )
    }
}

// 第一个参数,表示导航栈内有哪些视图;
// 第二个是配置参数(可选)
const RootStack = StackNavigator(
    {
        HomeScreen: {
            screen: HomeScreen,
        },
        SecondScreen: {
            screen: SecondScreen,
        },
    },
    {
        initialRouteName: 'HomeScreen',
    }
);

1.4双屏切换与数据传递

(1)、在主屏(HomeScreen)设置Button,并添加点击,关联到this.props.navigation.navigate('SecondScreen'),这样点击Button会跳转到新界面,修改HomeScreen代码如下:

export default class HomeScreen extends Component {
    static navigationOptions = ({ navigation }) => {
        return {
            header: () => null, // 隐藏头部
        }
    }

    render() {
        const { navigate } = this.props.navigation;
        return (
            <View>
                <Text style={{fontSize: 32}}>我是主屏</Text>
                <Button title="Next" onPress={()=> navigate('SecondScreen')}/>
            </View>
        )
    }
}

this.props.navigation,这个属性会被设置到所有StackNavigator中的页面

navigate('BookDetail'),将页面名称传入该方法,可以跳转到指定的StackNavigator页面

如果该名称传入错误,什么也不会发生。

如果在BookDetail页面再添加一个Button跳转到Details页面,页面会一直被添加。

(2)、StackNavigator会在非首屏提供一个返回箭头,提供返回操作。

也可以通过添加按钮关联goback返回。

此外,StackNavigator自动关联了安卓的返回键,点击设备的返回键也可以返回。

修改SecondScreen 如下:

export default class SecondScreen extends Component {
    static navigationOptions = ({ navigation }) => {
        return {
            header: ()=>  <Text style={{fontSize: 32}}>我是第二屏</Text>
        }
    }
    render() {
        const { navigate } = this.props.navigation;
        return (
            <View>
                <Text>SecondScreen</Text>
                <Button title = 'Next' onPress = {()=> navigate('SecondScreen')}/>
                <View style={{height:20}}/>
                <Button title="Previous" onPress={() => navigate.goBack()}/>
            </View>
        )
    }
}

1.5、附加内容(可不看)

这里大家可能对navigate、goback等不理解,下面讲解下

在导航器中的每一个页面,都有 navigation 属性,该属性有以下几个属性/方法:  

navigate     跳转到其他页面 
state        当前页面导航器的状态
setParams    更改路由的参数 
goBack       返回 
dispatch     发送一个action

navigete调用这个方法可以跳转到导航器中的其他页面,此方法有三个参数:


routeName    导航器中配置的路由名称
params       传递参数到下一个页面
action       action

比如: this.props.navigation.navigate('Find', {param: 'i am the param'});

state 里面包含有传递过来的参数 params 、 key 、路由名称 routeName ,打印log可以看得到:

{ 
  params: { param: 'i am the param' },
  key: 'id-1500546317301-1',
  routeName: 'Mine' 
}

setParams更改当前页面路由的参数,比如可以用来更新头部的按钮或者标题。

componentDidMount() {
    this.props.navigation.setParams({param:'i am the new param'})
}

goBack 回退,可以不传,也可以传参数,还可以传 null 。

this.props.navigation.goBack();       // 回退到上一个页面
this.props.navigation.goBack(null);   // 回退到任意一个页面
this.props.navigation.goBack('Home'); // 回退到Home页面

附加内容结束


1.6、传递参数

通过在调用navigate方法时传入一个对象

this.props.navigation.navigate('RouteName', { /* params go here */ })

(1)、修改HomeScreen中Button,增加参数页数

    render() {
        const { navigate } = this.props.navigation;
        return (
            <View>
                <Text style={{fontSize: 32}}>我是主屏</Text>
                <Button title="Next" onPress={()=> navigate('SecondScreen',{page: 0})}/>
            </View>
        )
    }

(2)、修改SecondScreen,读取页数,并显示

render() {
    const { navigation } = this.props.navigation;
    // 设置变量存放页数
    let ID = this.props.navigation.state.params.page+1;
    return (
        <View>
            <Text>SecondScreen 第{ ID }页</Text>
            <Button title = 'Next' onPress = {()=> this.props.navigation.navigate('SecondScreen',{page: ID })}/>
            <View style={{height:20}}/>
            <Button title="Previous" onPress={() => this.props.navigation.goBack()}/>
        </View>
    )
}

1.7、效果如下:

1.8、最后补充下navigationOptions

通过它配置一些参数,例如title (ios默认会居中,android居左),

(1)如我把标题设置为空

    static navigationOptions = ({ navigation }) => {
        return {
            header: () => null, // 隐藏头部
        }
    }

  或者设置为具体名字

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

(2)  将this.props放入navigationOptions中使用看起来很方便,

但因为这是个静态属性,所以实际上并不会关联到任何实例,自然也不会有props属性。

这里需要将navigationOptions变成一个方法,

React Navigation会通过一个包含{navigation, navigationOptions, screenProps}的对象调用它。

(3)传递参数设置navigationOptions

传入导航选项函数的参数是一个具有以下属性的对象:

navigation(导航栏) - The navigation prop for the screen, with the screen's route at navigation.state. 
screenProps(屏幕属性) - 从上层导航器组件传过来的参数
navigationOptions(导航选项) - 如果不提供新值,则将使用的默认或先前选项。

static navigationOptions = ({ navigation }) => {
    // 注意params是带大括号的
    const { params } = navigation.state;
    
    return {
      title: params ? params.otherParam : 'A Nested Details Screen',
    }
  };

(4)在当前屏幕对navigationOptions进行更新

<Button
    title="Update the title"
    onPress={() => this.props.navigation.setParams({otherParam: 'Updated!'})}
  />

(5)调整头部样式。

主要用到三个属性
headerStyle:       设置包裹头部view的样式,可以设置背景颜色
headerTintColor:   渲染返回键、标题的颜色。
headerTitleStyle:  设置文字、字体、粗细(fontWeight)?
static navigationOptions = {
    title: 'Home',
    headerStyle: {
      backgroundColor: '#f4511e',
    },
    headerTintColor: '#fff',
    headerTitleStyle: {
      fontWeight: 'bold',
    },
  };

注意:这种设置方式只对当前页面有效。

(6)如果要配置对所有导航页都有效的样式,应该在StackNavigator的第二个参数中配置

const RootStack = StackNavigator(
  {
    Home: {
      screen: HomeScreen,
    },
    Details: {
      screen: SecondScreen,
    },
  },
  {
    initialRouteName: 'Home',
    /* The header config from HomeScreen is now here */
    navigationOptions: {
      headerStyle: {
        backgroundColor: '#f4511e',
      },
      headerTintColor: '#fff',
      headerTitleStyle: {
        fontWeight: 'bold',
      },
    },
  }
);

这样所有的样式就一样了,如果某个页面要设置特殊样式,可以单独设置StackNavigator。

也可以通过将公共的navigationOptions 通过对象传入进行修改。

(7)、自定义一个组件作为标题

// 定义一个标题
class LogoTitle extends React.Component {
  render() {
    return (
      <Text style ={ {flex:1, fontSize:30,color:'green',textAlign:'center'}}>
      标题
      </Text>
    );
  }
}

//引用
class HomeScreen extends React.Component {
 
  static navigationOptions = {
    // title: 'Home',
    headerTitle:<LogoTitle/>,
  };

//或者
class BookDetail extends Component {
    static navigationOptions = ({ navigation }) => {
        return {
            //使用自己定义的头部
            header: () => <LogoTitle/>,
        }
    };

相关API可以查看StackNavigator reference

2、TabNavigator:   类似底部导航栏,用来在同一屏切换不同页面


3、DrawerNavigator:侧滑菜单导航栏,用于轻松设置带抽屉的屏幕

4、属性介绍

参考链接:摘抄自

4.1、StackNavigator属性介绍

navigationOptions:配置StackNavigator的一些属性。
 
title:标题,如果设置了这个导航栏和标签栏的title就会变成一样的,不推荐使用
header:可以设置一些导航的属性,如果隐藏顶部导航栏只要将这个属性设置为null
headerTitle:设置导航栏标题,推荐
headerBackTitle:设置跳转页面左侧返回箭头后面的文字,默认是上一个页面的标题。可以自定义,也可以设置为null
headerTruncatedBackTitle:设置当上个页面标题不符合返回箭头后的文字时,默认改成"返回"
headerRight:设置导航条右侧。可以是按钮或者其他视图控件
headerLeft:设置导航条左侧。可以是按钮或者其他视图控件
headerStyle:设置导航条的样式。背景色,宽高等
headerTitleStyle:设置导航栏文字样式
headerBackTitleStyle:设置导航栏‘返回’文字样式
headerTintColor:设置导航栏颜色
headerPressColorAndroid:安卓独有的设置颜色纹理,需要安卓版本大于5.0
gesturesEnabled:是否支持滑动返回手势,iOS默认支持,安卓默认关闭

screen:对应界面名称,需要填入import之后的页面
mode:定义跳转风格
card:使用iOS和安卓默认的风格
modal:iOS独有的使屏幕从底部画出。类似iOS的present效果
headerMode:返回上级页面时动画效果
float:iOS默认的效果
screen:滑动过程中,整个页面都会返回
none:无动画
cardStyle:自定义设置跳转效果
transitionConfig: 自定义设置滑动返回的配置
onTransitionStart:当转换动画即将开始时被调用的功能
onTransitionEnd:当转换动画完成,将被调用的功能
path:路由中设置的路径的覆盖映射配置
initialRouteName:设置默认的页面组件,必须是上面已注册的页面组件
initialRouteParams:初始路由参数

4.2、TabNavigator属性介绍

screen:和导航的功能是一样的,对应界面名称,可以在其他页面通过这个screen传值和跳转。
navigationOptions:配置TabNavigator的一些属性
title:标题,会同时设置导航条和标签栏的title
tabBarVisible:是否隐藏标签栏。默认不隐藏(true)
tabBarIcon:设置标签栏的图标。需要给每个都设置
tabBarLabel:设置标签栏的title。推荐

导航栏配置
tabBarPosition:设置tabbar的位置,iOS默认在底部,安卓默认在顶部。(属性值:'top','bottom') 
swipeEnabled:是否允许在标签之间进行滑动
animationEnabled:是否在更改标签时显示动画
lazy:是否根据需要懒惰呈现标签,而不是提前,意思是在app打开的时候将底部标签栏全部加载,默认false,推荐为true
trueinitialRouteName: 设置默认的页面组件
backBehavior:按 back 键是否跳转到第一个Tab(首页), none 为不跳转
tabBarOptions:配置标签栏的一些属性iOS属性
activeTintColor:label和icon的前景色 活跃状态下
activeBackgroundColor:label和icon的背景色 活跃状态下
inactiveTintColor:label和icon的前景色 不活跃状态下
inactiveBackgroundColor:label和icon的背景色 不活跃状态下
showLabel:是否显示label,默认开启 style:tabbar的样式
labelStyle:label的样式安卓属性
activeTintColor:label和icon的前景色 活跃状态下
inactiveTintColor:label和icon的前景色 不活跃状态下
showIcon:是否显示图标,默认关闭
showLabel:是否显示label,默认开启 style:tabbar的样式
labelStyle:label的样式 upperCaseLabel:是否使标签大写,默认为true
pressColor:material涟漪效果的颜色(安卓版本需要大于5.0)
pressOpacity:按压标签的透明度变化(安卓版本需要小于5.0)
scrollEnabled:是否启用可滚动选项卡 tabStyle:tab的样式
indicatorStyle:标签指示器的样式对象(选项卡底部的行)。安卓底部会多出一条线,可以将height设置为0来暂时解决这个问题
labelStyle:label的样式
iconStyle:图标样式

4.3、DrawerNavigator属性介绍

DrawerNavigatorConfig

drawerWidth - 抽屉的宽度
drawerPosition - 选项是左或右。 默认为左侧位置
contentComponent - 用于呈现抽屉内容的组件,例如导航项。 接收抽屉的导航。 默认为DrawerItems
contentOptions - 配置抽屉内容

initialRouteName - 初始路由的routeName
order - 定义抽屉项目顺序的routeNames数组。
     路径 - 提供routeName到路径配置的映射,它覆盖routeConfigs中设置的路径。
     backBehavior - 后退按钮是否会切换到初始路由? 如果是,设置为initialRoute,否则为none。 默认为initialRoute行为

DrawerItems的contentOptions属性

activeTintColor - 活动标签的标签和图标颜色
activeBackgroundColor - 活动标签的背景颜色
inactiveTintColor - 非活动标签的标签和图标颜色
inactiveBackgroundColor - 非活动标签的背景颜色
内容部分的样式样式对象
labelStyle - 当您的标签是字符串时,要覆盖内容部分中的文本样式的样式对象

猜你喜欢

转载自blog.csdn.net/jinmie0193/article/details/81361777