React Native导航库react-navigation详细教程

Viewed 0

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导出。目前只有一个空的导航,和中间的文字。

注意:在React Native中,在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、附加内容(可不看)

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

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

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

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

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

state 里面包含有传递过来的参数 paramskey、路由名称 routeName

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');

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:导航栏,包含屏幕的路由在navigation.state。
  • screenProps:从上层导航器组件传过来的参数。
  • navigationOptions:如果不提供新值,则将使用的默认或先前选项。
static navigationOptions = ({ navigation }) => {
  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',
    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 = {
    headerTitle: <LogoTitle />,
  };
}

class BookDetail extends Component {
  static navigationOptions = ({ navigation }) => {
    return {
      header: () => <LogoTitle />,
    }
  };
}

相关API可以查看 StackNavigator reference

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

TabNavigator用于创建底部导航栏,允许在同一屏幕上切换不同页面。使用方式类似StackNavigator,但专注于标签导航,适合需要快速切换多个功能模块的应用场景。

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

DrawerNavigator用于创建侧滑菜单导航栏,提供抽屉式导航体验。配置和使用方法与StackNavigator和TabNavigator类似,常用于需要隐藏导航选项或提供更多设置选项的应用。

4、属性介绍

以下是对StackNavigator、TabNavigator和DrawerNavigator的常见属性介绍,帮助开发者更好地配置导航组件。

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。
  • initialRouteName:设置默认的页面组件。
  • 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:当您的标签是字符串时,要覆盖内容部分中的文本样式的样式对象。
0 Answers