React Native 导航器详解:React Navigation 入门指南

Viewed 0

React Native 导航器详解:React Navigation 入门指南

React Navigation 是 React Native 中一款强大的导航组件,被视为 Navigator 的增强版。它支持底部导航(类似 iOS 中的 UITabBarController)以及侧拉抽屉效果(类似 Android 中的 DrawerLayout),为移动应用提供灵活的导航结构。

导航器概述

导航器可以看作普通的 React 组件,用于定义应用的导航结构。它还能渲染通用元素,如标题栏、底部标签栏和顶部选项卡栏。在 React Navigation 中,主要包含以下七种导航器类型:

  1. createStackNavigator:类似标准的 Navigator,提供屏幕上方导航栏。
  2. createBottomTabNavigator:替代已弃用的 createTabNavigator,实现屏幕底部导航栏。
  3. createMaterialTopTabNavigator:屏幕顶部的材料设计主题标题栏。
  4. createDrawerNavigator:侧边滑出的抽屉效果导航。
  5. createSwitchNavigator:一次只显示一个页面,常用于身份验证流程。
  6. 此外,还有 createTabNavigator(已弃用)等。

在学习这些导航器之前,需要先理解两个核心概念:Screen navigation prop(屏幕导航属性)和 Screen navigationOptions(屏幕导航选项)。通过 navigation prop,可以完成屏幕之间的调度操作;而 navigationOptions 用于定制导航器显示屏幕的方式,例如设置头部标题或选项卡标签。

Screen Navigation Prop 详解

当导航器中的屏幕被打开时,它会接收一个 navigation prop,这是导航环节的关键。navigation prop 提供以下主要功能:

  • navigate:跳转到其他页面。
  • state:获取屏幕当前状态。
  • setParams:改变路由的参数。
  • goBack:关闭当前屏幕。
  • dispatch:向路由发送一个 action。
  • addListener:订阅导航生命周期的更新。
  • isFocused:标志屏幕是否获取焦点。
  • getParam:获取特定参数。
  • dangerouslyGetParent:返回父导航器。

使用 navigation.navigate 进行界面跳转的基本语法为 navigation.navigate(routeName, params, action)navigation.navigate({routeName, params, action, key})。其中,routeName 是要跳转界面的路由名,params 是传递给下一个界面的参数,action 用于子导航操作,key 是可选的标识符。

常用导航器解析

createStackNavigator

createStackNavigator 提供应用屏幕之间的切换能力,以栈的形式管理导航,新切换到的屏幕会置于栈顶。默认转场效果在 Android 上为底部淡入,在 iOS 上为右侧划入,但可通过配置自定义。

API 格式:createStackNavigator(RouteConfigs, StackNavigatorConfig)。RouteConfigs 是必选的路由配置对象,定义路由名称到路由配置的映射;StackNavigatorConfig 为可选的导航器配置。

基本使用步骤:

  1. 安装依赖:yarn add react-navigation
  2. 添加手势处理:yarn add react-native-gesture-handler
  3. 链接原生模块:react-native link react-native-gesture-handler

createMaterialTopTabNavigator 与 createBottomTabNavigator

createMaterialTopTabNavigator 用于屏幕顶部标签栏,而 createBottomTabNavigator 用于底部标签栏。它们的 API 类似:createNavigator(RouteConfigs, TabNavigatorConfig)

TabNavigatorConfig 特有配置包括:

  • tabBarComponent:指定 TabBar 组件。
  • tabBarPosition:标签栏位置,支持 'top' 或 'bottom'。
  • swipeEnabled:是否允许左右滑动切换标签。
  • lazy:设置为 true 时可实现标签页懒加载。
  • animationEnabled:切换页面时是否启用动画效果。
  • tabBarOptions:配置标签栏样式,如 activeTintColor(选中颜色)、inactiveTintColor(未选中颜色)、showIcon(是否显示图标)、style(整体样式)等。

createDrawerNavigator

createDrawerNavigator 实现侧边抽屉导航。其配置参数 DrawerNavigatorConfig 包括:

  • drawerWidth:设置侧边菜单宽度。
  • drawerPosition:菜单位置,支持 'left' 或 'right'。
  • contentComponent:自定义侧边栏内容组件,默认使用 DrawerItems。
  • contentOptions:配置侧边栏项属性,如 activeTintColor、inactiveBackgroundColor 等。
  • drawerBackgroundColor:侧边菜单背景色。

自定义侧边栏时,可通过重写 contentComponent 来渲染自定义组件,例如结合 ScrollView 和 SafeAreaView 适配全面屏。

createSwitchNavigator

createSwitchNavigator 用于一次仅显示一个页面的场景,如登录流程。默认不处理返回操作,并在切换时重置路由状态。

API:createSwitchNavigator(RouteConfigs, SwitchNavigatorConfig)。SwitchNavigatorConfig 支持 initialRouteName(初始路由)、resetOnBlur(离开屏幕时是否重置状态)等配置。

代码示例与整合

以下是一个综合示例,展示如何整合多种导航器:

import React, {Component} from 'react';
import {Platform, Button, ScrollView, SafeAreaView, View} from 'react-native';
import {createStackNavigator, createMaterialTopTabNavigator, createBottomTabNavigator, createDrawerNavigator, DrawerItems, createSwitchNavigator} from 'react-navigation';
import Ionicons from 'react-native-vector-icons/Ionicons';
import MaterialIcons from 'react-native-vector-icons/MaterialIcons';
import HomePage from '../pages/HomePage';
import Page1 from '../pages/Page1';
import Page2 from '../pages/Page2';
import Page3 from '../pages/Page3';
import Page4 from '../pages/Page4';
import Page5 from '../pages/Page5';
import Login from '../pages/Login';

const AppStack = createStackNavigator({
  Home: { screen: HomePage },
  Page1: { screen: Page1 }
});

const AuthStack = createStackNavigator({
  Login: { screen: Login }
});

export const AppSwitchNavigator = createSwitchNavigator({
  Auth: AuthStack,
  App: AppStack
}, {
  initialRouteName: 'Auth'
});

const TopNavigator = createMaterialTopTabNavigator({
  Page1: { screen: Page1, navigationOptions: { tabBarLabel: 'Android' } },
  Page2: { screen: Page2, navigationOptions: { tabBarLabel: 'iOS' } },
  Page3: { screen: Page3, navigationOptions: { tabBarLabel: 'React' } },
  Page4: { screen: Page4, navigationOptions: { tabBarLabel: 'React Native' } },
  Page5: { screen: Page5, navigationOptions: { tabBarLabel: 'My Pleasure' } }
}, {
  tabBarOptions: {
    tabStyle: { minWidth: 50 },
    upperCaseLabel: false,
    scrollEnabled: true,
    style: { backgroundColor: '#678' },
    indicatorStyle: { height: 2, backgroundColor: 'pink' },
    labelStyle: { fontSize: 13, marginTop: 6, marginBottom: 6 }
  }
});

const BottomNavigator = createBottomTabNavigator({
  Page1: { 
    screen: Page1, 
    navigationOptions: { 
      tabBarLabel: '最热', 
      tabBarIcon: ({tintColor}) => <Ionicons name={'ios-home'} size={26} style={{color: tintColor}} />
    }
  },
  Page2: { 
    screen: Page2, 
    navigationOptions: { 
      tabBarLabel: '趋势', 
      tabBarIcon: ({tintColor}) => <Ionicons name={'ios-people'} size={26} style={{color: tintColor}} />
    }
  },
  Page3: { 
    screen: Page3, 
    navigationOptions: { 
      tabBarLabel: '收藏', 
      tabBarIcon: ({tintColor}) => <Ionicons name={'ios-chatboxes'} size={26} style={{color: tintColor}} />
    }
  },
  Page4: { 
    screen: Page4, 
    navigationOptions: { 
      tabBarLabel: '我的', 
      tabBarIcon: ({tintColor}) => <Ionicons name={'ios-aperture'} size={26} style={{color: tintColor}} />
    }
  }
}, {
  tabBarOptions: { activeTintColor: 'red' }
});

const DrawerNavigator = createDrawerNavigator({
  Page4: { 
    screen: Page4, 
    navigationOptions: { 
      drawerLabel: 'Page4', 
      drawerIcon: ({tintColor}) => <MaterialIcons name={'drafts'} size={24} style={{color: tintColor}} />
    }
  },
  Page5: { 
    screen: Page5, 
    navigationOptions: { 
      drawerLabel: 'Page5', 
      drawerIcon: ({tintColor}) => <MaterialIcons name={'move-to-inbox'} size={24} style={{color: tintColor}} />
    }
  }
}, {
  initialRouteName: 'Page4',
  contentOptions: { activeTintColor: '#e91e63' },
  contentComponent: (props) => (
    <ScrollView style={{backgroundColor: '#789', flex: 1}}>
      <SafeAreaView forceInset={{top: 'always', horizontal: 'never'}}>
        <DrawerItems {...props} />
      </SafeAreaView>
    </ScrollView>
  ),
  drawerLockMode: 'unlocked'
});

export const AppStackNavigator = createStackNavigator({
  HomePage: { screen: HomePage },
  Page1: { 
    screen: Page1, 
    navigationOptions: ({navigation}) => ({ title: `${navigation.state.params.name}页面名` })
  },
  Page2: { screen: Page2, navigationOptions: { title: 'This is Page2' } },
  Page3: { 
    screen: Page3, 
    navigationOptions: (props) => {
      const {navigation} = props;
      const {state, setParams} = navigation;
      const {params} = state;
      return {
        title: params.title ? params.title : 'This is Page3',
        headerRight: (
          <Button 
            title={params.mode === 'edit' ? '保存' : '编辑'} 
            onPress={() => setParams({mode: params.mode === 'edit' ? '' : 'edit'})} 
          />
        )
      };
    }
  },
  Page4: { screen: Page4, navigationOptions: { title: 'This is Page4' } },
  Bottom: { screen: BottomNavigator, navigationOptions: { title: 'BottomNavigator' } },
  Top: { screen: TopNavigator, navigationOptions: { title: 'TopNavigator' } },
  DrawerNav: { screen: DrawerNavigator, navigationOptions: { title: 'DrawerNav' } }
});

此示例展示了如何结合多种导航器构建复杂应用结构,具体代码可参考相关资源进行扩展。通过合理配置导航器,可以高效管理 React Native 应用的页面切换和用户流程。

0 Answers