React Navigation 5.x教程與配置詳解

一、簡介

React Navigation是React Native是目前最主流的屏幕頁面切換的導航方案。React Navigation 5.x版本是目前最新的穩(wěn)定版本,相對于老版本的配置方式更接近React Router,更好理解。
reactNative0.60.0以上的版本會省去很多配置,建議使用0.6以上版本
npx react-native init demo --version 0.60.0 //版本號自行定義

二、依賴安裝

// 安裝react-navigation
yarn add @react-navigation/native
// 安裝依賴庫
yarn add react-native-gesture-handler react-native-reanimated react-native-screens react-native-safe-area-context @react-native-community/masked-view

注意:鏈接原生庫(0.60版本以上的跳過此步驟)
React Native 0.60及更高版本開始,會自動鏈接,如果你版本是0.60及以上,這一步就可以跳過;而React Native 0.59以及更低版本則需要手動鏈接,安裝react-native link。

   react-native link react-native-reanimated
   react-native link react-native-gesture-handler
   react-native link react-native-screens
   react-native link react-native-safe-area-context

安裝navigator庫
有三種導航模式可以選,分別是StackNavigator棧導航、TabNavigator標簽導航、DrawerNavigator抽屜導航,下面會分別說一下怎么使用。

   //StackNavigator
   npm install @react-navigation/stack
   //TabNavigator
   npm install @react-navigation/bottom-tabs
   //DrawerNavigator
   npm install @react-navigation/drawer

三、StackNavigator導航

使用教程:

1.引入組件

   import { NavigationContainer } from '@react-navigation/native';
   import { createStackNavigator } from '@react-navigation/stack';

2.創(chuàng)建棧導航
createStackNavigator提供APP屏幕之間切換的能力,它是以棧的形式來管理屏幕之間的切換,新切換到的屏幕會放在棧的頂部。

   const Stack = createStackNavigator();

3.將需要進行屏幕切換的組件放入棧導航里

   function App() {
     return (
       <NavigationContainer>
         <Stack.Navigator>
           <Stack.Screen name="Home" component={HomeScreen} />
         </Stack.Navigator>
       </NavigationContainer>
     );
   }

4.完整代碼

app/views/LoginScreen.js

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

export default class HomeScreen extends Component {
    constructor(props) {
        super(props);
    }

    render() {
        return (
            <View>
                <TouchableOpacity  onPress={() => this.props.navigation.navigate('Home')}>
                    <Text >跳轉(zhuǎn)首頁</Text>
                </TouchableOpacity>
            </View>
        )
    }
}

app/views/HomeScreen.js

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

export default class HomeScreen extends Component {
  constructor(props) {
    super(props);
  }
  render() {
    return (
      <View>
        <TouchableOpacity  onPress={() => this.props.navigation.navigate('Login')}>
          <Text >跳轉(zhuǎn)登陸</Text>
        </TouchableOpacity>
      </View>
    )
  }
}

App.js

import 'react-native-gesture-handler';
import React, { Component } from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
//引入頁面模塊
import LoginScreen from './app/views/LoginScreen';
import HomeScreen from './app/views/HomeScreen';

const Stack = createStackNavigator();

function App() {
  return (
    <NavigationContainer>
      <Stack.Navigator>
        <Stack.Screen name="Login" component={LoginScreen} />
        <Stack.Screen name="Home" component={HomeScreen} />
      </Stack.Navigator>
    </NavigationContainer>
  );
}

export default App;

詳細參數(shù)與配置說明

  • Stack.Navigator的配置選項
    1. initialRouteName
      首次加載名稱
    2. screenOptions
      屏幕的默認選項。如下示例。
<Stack.Navigator
initialRouteName="Page1"     //作為初始化頁面、不寫的話默認第一個screen為初始化頁面
screenOptions={{                 //用來定制頭部信息、根據(jù)自己需要更改
  title: '測試標題',
  headerStyle: {
    backgroundColor: '#ee7530'
  },
  headerTintColor: '#fff',
  headerTitleStyle: {
    fontWeight: 'bold',
    fontSize: 20
  }
}}>
  1. keyboardHandlingEnabled
    如果為false,則導航到新屏幕時,屏幕鍵盤不會自動關閉。默認為true
  2. mode
    定義渲染和過渡的樣式
    card:使用標準的iOS和Android屏幕過渡。這是默認值.
    modal:這有兩件事:設置headerMode到screen堆棧,除非指定使屏幕從iOS底部的底部滑入,這是一種常見的iOS模式.
  3. headerMode
    指定標題的呈現(xiàn)方式
    float:渲染停留在頂部的單個標題,并在更改屏幕時進行動畫處理。iOS上的常見模式。
    screen:每個屏幕都有一個附加的標題,標題隨屏幕一起淡入和淡出。Android上的常見模式。
    none :沒有標題。
  • Stack.Screen的配置選項
    options
    可用于配置導航器內(nèi)的各個屏幕
    title
    頭部標題
function StackScreen() {
  return (
    //  靜態(tài)值
    <Stack.Navigator>
      <Stack.Screen
        name="Home"
        component={HomeScreen}
        options={{ title: 'My home' }}
      />
      // 動態(tài)獲取
      <Stack.Screen
        name="Profile"
        component={HomeScreen}
        options={({ route }) => ({ title: route.params.name })}
      />
    </Stack.Navigator>
  );
}
/* 在組件中修改使用setOptions */
    <Button
      title="Update the title"
      onPress={() => navigation.setOptions({ title: 'Updated!' })}
    />

header
函數(shù),返回一個React Element,顯示為標題。如下示例。

    header: ({ scene, previous, navigation }) => {
          const { options } = scene.descriptor;
          const title =
            options.headerTitle !== undefined
              ? options.headerTitle
              : options.title !== undefined
              ? options.title
              : scene.route.name;
        
          return (
            <MyHeader
              title={title}
              leftButton={
                previous ? <MyBackButton onPress={navigation.goBack} /> : undefined
              }
              style={options.headerStyle}
            />
          );
        };

headerShown
是顯示還是隱藏屏幕標題。默認情況下顯示標題,除非將headerMode其設置為none。設置為 false隱藏標題。在特定屏幕上隱藏標題時,您可能還需要將headerModeprop 設置為screen。
headerTitle
字符串或返回標頭要使用的React元素的函數(shù)。默認為 title 選項值.

function LogoTitle() {
  return (
    <Image
      style={{ width: 50, height: 50 }}
      source={require('@expo/snack-static/react-native-logo.png')}
    />
  );
}

function StackScreen() {
  return (
    <Stack.Navigator>
      <Stack.Screen
        name="Home"
        component={HomeScreen}
        options={{ headerTitle: props => <LogoTitle {...props} /> }}
      />
    </Stack.Navigator>
  );
}

headerTitleAlign
對齊標題??蛇x擇left或center。默認為iOS-center和Android-left
headerTitleAllowFontScaling
標頭標題字體是否應縮放以符合“文本大小”輔助功能設置。默認為false。
headerBackAllowFontScaling
后退按鈕標題字體是否應縮放以符合“文本大小”輔助功能設置。默認為false。
headerBackImage
該函數(shù)返回一個React Element以在標題的后退按鈕中顯示自定義圖像。使用函數(shù)時,它將tintColor在其參數(shù)對象中接收。默認為帶有背面圖像源的Image組件,它是平臺的默認背面圖標圖像(iOS上為人字形,Android上為箭頭)。
headerBackTitle
iOS上的后退按鈕使用的標題字符串。默認為上一個場景的headerTitle。
headerBackTitleVisible
為后退按鈕標題是否可見提供了一個合理的默認值,但是如果您想覆蓋它,則可以使用true或false在此選項中使用
headerTruncatedBackTitle
當headerBackTitle屏幕上不適合顯示后退按鈕時使用的標題字符串。"Back"默認情況下。
headerRight
該函數(shù)返回一個React元素以顯示在標題的右側。

function StackScreen() {
  return (
    <Stack.Navigator>
      <Stack.Screen
        name="Home"
        component={HomeScreen}
        options={{
          headerTitle: props => <LogoTitle {...props} />,
          headerRight: () => (
            <Button
              onPress={() => alert('This is a button!')}
              title="Info"
              color="#fff"
            />
          ),
        }}
      />
    </Stack.Navigator>
  );
}

headerLeft
返回React元素以顯示在標題左側的函數(shù)。使用函數(shù)時onPress,在呈現(xiàn)時它會接收許多參數(shù)(label,labelStyle和more-檢查types.tsx以獲取完整列表)。
headerStyle
標頭的樣式對象。例如,您可以在此處指定自定義背景色。
headerTitleStyle
標題組件的樣式對象
headerBackTitleStyle
標題的樣式對象
headerLeftContainerStyle
自定義headerLeft組件容器的樣式,例如添加填充。
headerRightContainerStyle
自定義headerRight組件容器的樣式,例如添加填充。
headerTitleContainerStyle
自定義headerTitle組件容器的樣式,例如添加填充。默認情況下,headerTitleContainerStyle是具有絕對位置的風格和偏移量都left和right。這可能導致的空白或之間重疊headerLeft和headerTitle如果定制headerLeft被使用??梢酝ㄟ^在中和中進行調(diào)整left和right樣式來解決。headerTitleContainerStylemarginHorizontalheaderTitleStyle
headerTintColor
標頭的色調(diào)顏色
headerPressColorAndroid
材料波紋的顏色(僅適用于Android> = 5.0)
headerTransparent
默認為false。如果為true,則標題將沒有背景,除非您明確為其提供背景headerBackground。標頭也將浮動在屏幕上,使其與下面的內(nèi)容重疊。
headerBackground
返回React元素以呈現(xiàn)為標題背景的函數(shù)。這對于使用背景(例如圖像或漸變)很有用。
例如,可以將其headerTransparent用于渲染模糊視圖以創(chuàng)建半透明標題。參考下述示例.

import { BlurView } from 'expo-blur';
<Screen
  name="Home"
  component={HomeScreen}
  options={{
    headerTransparent: true,
    headerBackground: () => (
      <BlurView tint="light" intensity={100} style={StyleSheet.absoluteFill} />
    ),
  }}
/>;

headerStatusBarHeight
在標題頂部添加額外的填充以說明半透明的狀態(tài)欄。默認情況下,它使用設備安全區(qū)域插圖中的最大值。傳遞0或自定義值以禁用默認行為,并自定義高度。
cardShadowEnabled
使用此道具在過渡期間具有可見的陰影。默認為true。
cardOverlayEnabled
使用此道具可以在過渡期間在卡下看到半透明的深色覆蓋層。默認為trueAndroid和falseiOS。
cardStyle
堆棧中卡的樣式對象。您可以在此處提供自定義背景色,以代替默認背景。您還可以指定{ backgroundColor: ‘transparent’ }使前一個屏幕在下面可見(對于透明模式)。這對于實現(xiàn)模態(tài)對話框之類的東西很有用。mode: 'modal’使用透明背景時,還應該在堆棧視圖配置中指定,這樣以前的屏幕就不會分離并且在下面保持可見。
animationEnabled
屏幕上是否應啟用過渡動畫。如果將其設置為false,則按下或彈出時屏幕不會動畫。默認為true。
animationTypeForReplace
當此屏幕替換另一個屏幕時要使用的動畫類型。它采用以下值:
push -將使用推送新屏幕的動畫
pop -將使用彈出屏幕的動畫
默認為push。
當pop被使用時,pop動畫被施加到被替換的畫面。
gestureEnabled
是否可以使用手勢關閉此屏幕。默認為trueiOS,falseAndroid。
gestureResponseDistance
從屏幕邊緣開始覆蓋觸摸距離的對象,以識別手勢。該對象可以包含以下屬性:
horizontal- 數(shù)字 -水平方向的距離。默認為25。
vertical- 數(shù)字 -垂直方向的距離。默認值為135。
gestureVelocityImpact
決定手勢速度相關性的數(shù)字。默認值為0.3。
gestureDirection
手勢的方向。與動畫有關
transitionSpec
屏幕過渡的配置對象。與動畫有關.請點擊此處查看
cardStyleInterpolator
插卡各部分的插補樣式。與動畫有關請點擊此處查看
headerStyleInterpolator
標頭各部分的內(nèi)插樣式。與動畫有關請點擊此處查看
safeAreaInsets
屏幕的安全區(qū)域插圖。這用于避免使用諸如缺口和狀態(tài)欄之類的元素。默認情況下,將自動檢測設備的安全區(qū)域插圖。您可以使用此選項覆蓋行為。接受包含以下可選屬性的對象:
top- 數(shù)字 -頂部插圖的值,例如包含狀態(tài)欄和槽口的區(qū)域。
right- 數(shù)字 -左插圖的值。
bottom- 數(shù)字 -頂部插圖的值,例如底部的區(qū)域?qū)Ш綑凇?br> left。- 數(shù)字 -右插圖的值。

四、TabNavigator導航

底部導航欄,有的app開發(fā)的時候需要用到底部導航欄切換。使用方法跟StackNavigator類似。

1.安裝:
npm install @react-navigation/bottom-tabs
2.完整代碼
App.js

import 'react-native-gesture-handler';
import React, { Component } from 'react';
import { NavigationContainer } from '@react-navigation/native';
//導入
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
//引入頁面模塊
import LoginScreen from './app/views/LoginScreen';
import HomeScreen from './app/views/HomeScreen';

const Tab = createBottomTabNavigator();

function App() {
  return (
    <NavigationContainer>
      <Tab.Navigator 
        tabBarOptions={{
          activeTintColor: 'red',
          inactiveTintColor: 'gray',
          tabStyle : {
            backgroundColor: '#ddd',
            paddingBottom: 15,
            borderRightWidth: 1,
            borderRightColor: '#fff'
          },
        }}
      >
        <Tab.Screen name="Home" component={HomeScreen} options={{
          headerStyle: {
            backgroundColor: '#f4511e',
          },
          headerTintColor: '#fff',
          headerTitleStyle: {
            fontWeight: 'bold',
          },
        }} />
        <Tab.Screen name="Login" component={LoginScreen} />
      </Tab.Navigator>
    </NavigationContainer>
  );
}

export default App;

詳細參數(shù)與配置說明

Tab.Navigator的配置

  1. initialRouteName
    導航首次加載時要渲染的路線的名稱。

  2. screenOptions
    導航中用于屏幕的默認選項。

  3. backBehavior
    后退按鈕處理的行為。

    • initialRoute: 返回初始標簽
    • order: 返回上一個標簽頁(按照標簽頁中顯示的順序)
    • history: 返回上次訪問的標簽頁
    • none:不處理后退按鈕
  4. lazy
    默認為true。如果為false,則所有選項卡都將立即呈現(xiàn)。如果為true,則僅在首次使選項卡處于活動狀態(tài)時才顯示它們。注意:選項卡不會在后續(xù)訪問時重新呈現(xiàn)。

  5. tabBar
    返回React元素以顯示為選項卡欄的函數(shù)

  6. tabBarOptions
    包含選項卡欄組件的道具的對象。它可以包含以下屬性:

    • activeTintColor -活動標簽的標簽和圖標顏色。
    • activeBackgroundColor -活動標簽的背景顏色。
    • inactiveTintColor -非活動標簽的標簽和圖標顏色。
    • inactiveBackgroundColor -非活動標簽的背景顏色。
    • showLabel -是否顯示標簽標簽,默認為true。
    • showIcon -是否顯示標簽圖標,默認為true。
    • style -標簽欄的樣式對象。
    • labelStyle -標簽標簽的樣式對象。
    • labelPosition-在何處顯示與標簽圖標相關的標簽標簽??捎弥禐閎eside-icon和below-icon。默認為beside-icon。
    • tabStyle -標簽的樣式對象。
    • allowFontScaling -標簽字體是否應縮放以符合“文本大小”輔助功能設置,默認為true。
    • adaptive-標簽圖標和標簽對齊方式是否應根據(jù)屏幕尺寸而改變?true對于iOS 11 false,默認值為。如果,標簽圖標和標簽始終垂直對齊。當時true,標簽圖標和標簽在平板電腦上水平對齊。
    • safeAreaInset-覆蓋forceInset道具。默認為{ bottom: ‘a(chǎn)lways’, top: ‘never’ }??捎玫逆Itop | bottom | left | right隨值一起提供’always’ | ‘never’。
    • keyboardHidesTabBar-默認為false。如果true在鍵盤打開時隱藏標簽欄。

options 可用于配置導航內(nèi)的各個屏幕。支持的選項有:

  1. title
    通用標題可以用作備用headerTitle和tabBarLabel。
  2. tabBarVisible
    true或false顯示或隱藏標簽欄(如果未設置),則默認為true。
  3. tabBarIcon
    給定的函數(shù){ focused: boolean, color: string, size: number }返回一個React.Node,以顯示在選項卡欄中。
  4. tabBarLabel
    顯示在選項卡欄中的選項卡的標題字符串或給定的函數(shù)將{ focused: boolean, color: string }返回React.Node,以顯示在選項卡欄中。未定義時,使用場景title。
  5. tabBarButton
    該函數(shù)返回一個React元素以呈現(xiàn)為選項卡按鈕。它包裝圖標和標簽并實現(xiàn)onPress。TouchableWithoutFeedback默認情況下渲染。tabBarButton: props => <TouchableOpacity {…props} />會TouchableOpacity改為使用。
  6. tabBarAccessibilityLabel
    選項卡按鈕的輔助功能標簽。當用戶點擊選項卡時,屏幕閱讀器會讀取該內(nèi)容。如果您沒有標簽的標簽,建議您進行設置。
  7. tabBarTestID
    在測試中找到此選項卡按鈕的ID。
  8. unmountOnBlur
    離開該屏幕時是否應卸載該屏幕。卸載屏幕將重置屏幕中的任何本地狀態(tài)以及屏幕中嵌套導航器的狀態(tài)。默認為false。

五、DrawerNavigator導航

1.安裝:

npm install @react-navigation/drawer

2.完整代碼

App.js

import 'react-native-gesture-handler';
import React, { Component } from 'react';
import { NavigationContainer } from '@react-navigation/native';
//導入
import { createDrawerNavigator } from '@react-navigation/drawer';
//引入頁面模塊
import LoginScreen from './app/views/LoginScreen';
import HomeScreen from './app/views/HomeScreen';

const Drawer = createDrawerNavigator();

function App() {
  return (
    <NavigationContainer
      drawerStyle={{
        backgroundColor: '#c6cbef',
        width: 200,
      }}
    >
      <Drawer.Navigator initialRouteName='Home'>
        <Drawer.Screen name='Home' component={HomeScreen} />
        <Drawer.Screen name='Login' component={LoginScreen} />
      </Drawer.Navigator>
    </NavigationContainer>
  );
}

export default App;

六、組合使用

原生思維是TabNavigator中嵌套StackNavigator,但是這里建議StackNavigator中嵌套TabNavigator。因為可以避免控制TabNavigator的tabbar顯示和隱藏問題。

?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內(nèi)容