React Navigation 5.x和 6.x 最新教程

安裝


5.X
yarn 版本

yarn add @react-navigation/native

yarn add react-native-reanimated react-native-gesture-handler react-native-screens react-native-safe-area-context @react-native-community/masked-view

npm 版本

npm install @react-navigation/native

npm install react-native-reanimated react-native-gesture-handler react-native-screens react-native-safe-area-context @react-native-community/masked-view

react-native-reanimated 動(dòng)畫(huà)庫(kù)

react-native-gesture-handler 跨平臺(tái)手勢(shì)庫(kù)

react-native-screens 這個(gè)庫(kù)基本不會(huì)單獨(dú)使用,是react navigation的依賴,用原生代碼實(shí)現(xiàn)了Screen組件(可以查看pad 內(nèi) 相關(guān)代碼),讓頁(yè)面都存在在Screen上,不安裝的話,react-nvigation 會(huì)通過(guò)View實(shí)現(xiàn),性能會(huì)很差。

react-native-safe-area-context 安全區(qū)域組件庫(kù) safe-area

react-native-community/masked-view 帶蒙版的視圖

如果你的RN 版本>=0.60, linking 是自動(dòng) 你不需要 運(yùn)行 react-native link. 但是你需要 在進(jìn)行上面操作以后進(jìn)行下面操作?。。。?!

for ios

    cd ios 
    pod install

for android

進(jìn)入文件夾android/app/build.grade,在dependencies(依賴項(xiàng))里添加代碼(react-native-screens 相關(guān))

implementation 'androidx.appcompat:appcompat:1.1.0-rc01' 
implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0-alpha02'

在 android/app/src/main/java/下的MainActivity.java中對(duì)手勢(shì)系統(tǒng)操作
package com.swmansion.gesturehandler.react.example;

import com.facebook.react.ReactActivity;
import com.facebook.react.ReactActivityDelegate;
import com.facebook.react.ReactRootView;
import com.swmansion.gesturehandler.react.RNGestureHandlerEnabledRootView;

public class MainActivity extends ReactActivity {

  @Override
  protected String getMainComponentName() {
    return "應(yīng)用名";
  }

  @Override
  protected ReactActivityDelegate createReactActivityDelegate() {
    return new ReactActivityDelegate(this, getMainComponentName()) {
      @Override
      protected ReactRootView createRootView() {
       return new RNGestureHandlerEnabledRootView(MainActivity.this);
      }
    };
  }
}

為了使得android和iOS保持一致的體驗(yàn),必須重新封裝手勢(shì)系統(tǒng)

如果還是沒(méi)有解決問(wèn)題 點(diǎn)擊此處查看

最后操作 在index.js里添加

import 'react-native-gesture-handler'; 
// 如果不加這一行,在開(kāi)發(fā)時(shí)是好的,在線上版本很有可能閃退。

如果要想實(shí)現(xiàn)導(dǎo)航仍然需要安裝navigator庫(kù)
三種導(dǎo)航,分別為StackNavigator棧導(dǎo)航、TabNavigator標(biāo)簽導(dǎo)航、DrawerNavigator抽屜導(dǎo)航 項(xiàng)目中需要哪種就需要安裝相關(guān)依賴


6.X

yarn 版本

yarn add @react-navigation/native

yarn add  react-native-screens react-native-safe-area-context  react-native-gesture-handler 

npm 版本

npm install @react-navigation/native

npm install  react-native-screens react-native-safe-area-context  react-native-gesture-handler 

for ios

    cd ios 
    pod install

for android

進(jìn)入文件夾android/app/src/main/java/<your package name>/MainActivity.java ,添加代碼 (react-native-screens相關(guān))

@Override
protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(null);
}

并且導(dǎo)入頭文件

import android.os.Bundle;

其他操作

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

StackNavigator

1·安裝
//StackNavigator
npm install @react-navigation/stack

?? @react-navigation/stack 依賴 @react-native-community/masked-view 所以要確保 masked-view已經(jīng)安裝

介紹以及使用

createStackNavigator 返回一個(gè)實(shí)體包含了ScreenNavigator.他們是用來(lái)配置的navigator 的組件 ,并且Navigator組件 必須包裹著Screen組件

NavigationContainer 是一個(gè)處理Navigator樹(shù)navigation state,NavigationContainer必須在最外層。一般放在app.js中.
如果改變 改變某一個(gè)頁(yè)面的配置可以用 option進(jìn)行修改,統(tǒng)一修改那么用screenOptions 后面會(huì)詳細(xì)講解

//App.js

import * as React from 'react';
import { View, Text } from 'react-native';
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';

function HomeScreen({navigation}) {
  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
      <Text>Home Screen</Text>
      <Button
        title="Go to Details"
        onPress={() => navigation.push('Details', {
            itemId: 86,
            otherParam: 'anything you want here',
          })}/>
    </View>
  );
}
function DetailsScreen({navigation}) {
const { itemId, otherParam } = route.params;
  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
    <Text>Details Screen</Text>
    <Text>{itemId}</Text>
    <Text>{otherParam}</Text>
    <Button title="Go back" onPress={() => navigation.goBack()} />
    </View>
  );
}

const Stack = createStackNavigator();

function App() {
  return (
    <NavigationContainer>
      <Stack.Navigator>
        <Stack.Screen 
              name="Home" 
              options={{ title: 'Overview' }}
              initialParams={{ itemId: 42 }}
              component={HomeScreen} />
        <Stack.Screen name="Details" component={DetailsScreen} />
      </Stack.Navigator>
    </NavigationContainer>
  );
}

export default App;

1 傳值問(wèn)題

如果想傳遞更多其他的參數(shù)可以通過(guò)callback 形式傳遞 ,但是要注意添加了callback 需要自行添加 React.memo 或者 React.PureComponent避免沒(méi)有必要的渲染。

<Stack.Screen name="Home">
  {props => <HomeScreen {...props} extraData={someData} />}
</Stack.Screen>

navigate 到某一個(gè)界面 在本界面想要跳轉(zhuǎn)本頁(yè)面 需要修改navigatepush.如果想改變參數(shù)可以通過(guò)下面固定API進(jìn)行修改 。

        // 修改  Options 不會(huì)內(nèi)容不會(huì)發(fā)生修改 
        props.navigation.setOptions({
            title: 'hhhhhhh',
        })
        // 修改上一級(jí)頁(yè)面?zhèn)鬟^(guò)來(lái)的 Params 每一次修改會(huì)引起組件重新渲染 
        props.navigation.setParams({
            name: 'linzhiqinghaoshuai',
        })

如果想傳遞數(shù)據(jù)到上一個(gè)頁(yè)面,舉例而言 從 DetailsScreen 返回 HomeScreen 想要攜帶數(shù)據(jù)那么返回方法 需要修改pushnavigate

// Pass and merge params back to home screen
          navigation.navigate({
            name: 'Home',
            params: { post: postText }
          });

2 配置navigationBar

首先 要注意 配置 navigationBar 有兩個(gè)屬性
如果想要改變某一個(gè)頁(yè)面的配置可通過(guò)Stack.Screen節(jié)點(diǎn)里的option進(jìn)行修改,統(tǒng)一修改那么用Stack.Navigator節(jié)點(diǎn)里的screenOptions

  • Stack.Navigator的配置選項(xiàng)
  1. initialRouteName
    展示的默認(rèn)路由界面
  2. screenOptions
    屏幕參數(shù)設(shè)置
    2-1. headerStyle:配置頂部 header view
    2-2.headerTintColor: 返回按鈕和標(biāo)題的顏色
    2-3.headerTitleStyle: 標(biāo)題文字的顏色 Text.
<Stack.Navigator
    initialRouteName="Home"     //初始化頁(yè)面、不寫(xiě)的話默認(rèn)為 第一個(gè)screen為初始化頁(yè)面
    screenOptions={{                
      title: '我是標(biāo)題',
      headerStyle: {
        backgroundColor: 'red' // 背景色
      },
      headerTintColor: '#green', 
      headerTitleStyle: {
        fontWeight: 'bold',
        fontSize: 20
      }}}>
  1. keyboardHandlingEnabled
    導(dǎo)航到新頁(yè)面鍵盤(pán)是否關(guān)閉
  2. mode
    頁(yè)面跳轉(zhuǎn)的動(dòng)畫(huà)類型
    4-1.card:使用標(biāo)準(zhǔn)的iOS和Android屏幕過(guò)渡。默認(rèn)值.
    4-2. modal:由底邊往上.
  3. headerMode
    指定標(biāo)題的呈現(xiàn)方式
    5-1. float:頁(yè)面返回標(biāo)題漸變
    4-2. screen:頁(yè)面返回 標(biāo)題隨屏幕一起淡入和淡出。
    5-3. none :沒(méi)有標(biāo)題header bar。
  • Stack.Screen 的配置選項(xiàng)
      1. options
        • 1-1. title
          頭部標(biāo)題
        • 1-2. header
          函數(shù),返回一個(gè)React Element,顯示為標(biāo)題。
        • 1-3. headerShown
          是顯示還是隱藏屏幕標(biāo)題。默認(rèn)情況下顯示標(biāo)題,除非將headerMode其設(shè)置為none。設(shè)置為 false隱藏標(biāo)題。在特定屏幕上隱藏標(biāo)題時(shí),您可能還需要將headerModeprop 設(shè)置為screen。
        • 1-4. headerTitle
          字符串或返回標(biāo)頭要使用的React元素的函數(shù)。默認(rèn)為 title 選項(xiàng)值.
        • 1-5. headerTitleAlign
          對(duì)齊標(biāo)題??蛇x擇leftcenter。默認(rèn)為iOS-center和Android-left
        • 1-6. headerTitleAllowFontScaling
          標(biāo)頭標(biāo)題字體是否應(yīng)縮放以符合“文本大小”輔助功能設(shè)置。默認(rèn)為false。
        • 1-7. headerBackAllowFontScaling
          后退按鈕標(biāo)題字體是否應(yīng)縮放以符合“文本大小”輔助功能設(shè)置。默認(rèn)為false。
        • 1-8. headerBackImage
          該函數(shù)返回一個(gè)React Element以在標(biāo)題的后退按鈕中顯示自定義圖像。使用函數(shù)時(shí),它將tintColor在其參數(shù)對(duì)象中接收。默認(rèn)為帶有背面圖像源的Image組件,它是平臺(tái)的默認(rèn)背面圖標(biāo)圖像(iOS上為人字形,Android上為箭頭)。
        • 1-9. headerBackTitle
          iOS上的后退按鈕使用的標(biāo)題字符串。默認(rèn)為上一個(gè)場(chǎng)景的headerTitle。
        • 1-10. headerBackTitleVisible
          為后退按鈕標(biāo)題是否可見(jiàn)提供了一個(gè)合理的默認(rèn)值,但是如果您想覆蓋它,則可以使用truefalse在此選項(xiàng)中使用
        • 1-11. headerTruncatedBackTitle
          當(dāng)headerBackTitle屏幕上不適合顯示后退按鈕時(shí)使用的標(biāo)題字符串。"Back"默認(rèn)情況下。
        • 1-12. headerRight
          該函數(shù)返回一個(gè)React元素以顯示在標(biāo)題的右側(cè)。
        • 1-12. headerLeft
          返回React元素以顯示在標(biāo)題左側(cè)的函數(shù)。使用函數(shù)時(shí)onPress,在呈現(xiàn)時(shí)它會(huì)接收許多參數(shù)
          注意可以通過(guò) navigation.setOptions 改變相應(yīng)數(shù)值
function StackScreen() {
  return (
    <Stack.Navigator>
      <Stack.Screen
        name="Home"
        component={HomeScreen}
        options={({ navigation, route }) => ({
          headerTitle: props => <LogoTitle {...props} />,
        })}
      />
    </Stack.Navigator>
  );
}

function HomeScreen({ navigation }) {
  const [count, setCount] = React.useState(0);

  React.useLayoutEffect(() => {
    navigation.setOptions({
      headerRight: () => (
        <Button onPress={() => setCount(c => c + 1)} title="Update count" />
      ),
    });
  }, [navigation]);

  return <Text>Count: {count}</Text>;
}

.....and so on 更多點(diǎn)擊查看 詳情

TabNavigator

底部導(dǎo)航條,有的app開(kāi)發(fā)的時(shí)候需要用到底部導(dǎo)航欄切換。使用方法跟StackNavigator類似。注:如果 TabNavigatorStackNavigator 混和使用,可以用StackNavigatorTabNavigator 包裹起來(lái)。

1·安裝
npm install @react-navigation/bottom-tabs

代碼演示

import 'react-native-gesture-handler';
import React, { Component } from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import DetailsScreen from './DetailsScreen';
import HomeScreen from './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="Details" component={DetailsScreen} />
      </Tab.Navigator>
    </NavigationContainer>
  );
}

export default App;
2·TabNavigator 的配置選項(xiàng)
  1. initialRouteName

    首次加載時(shí)要渲染的路由名稱。

  2. screenOptions

    屏幕的默認(rèn)選項(xiàng)。

  3. backBehavior

    返回按鈕處理的行為。

  4. initialRoute

    返回初始標(biāo)簽

  5. order

    返回上一個(gè)標(biāo)簽頁(yè)(按照標(biāo)簽頁(yè)中顯示的順序)

  6. history

    返回上次訪問(wèn)的標(biāo)簽頁(yè)

  7. lazy

    默認(rèn)為true。如果為false,則所有選項(xiàng)卡都將立即呈現(xiàn)。如果為true,則僅在首次使選項(xiàng)卡處于活動(dòng)狀態(tài)時(shí)才顯示它們。注意:選項(xiàng)卡不會(huì)在后續(xù)訪問(wèn)時(shí)重新呈現(xiàn)。

  8. tabBar

    返回React元素

  9. tabBarOptions

    包含選項(xiàng)卡欄組件的配置對(duì)象。它可以包含以下屬性:

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

    可用于配置導(dǎo)航內(nèi)的各個(gè)屏幕。支持的選項(xiàng)有:

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

DrawerNavigator導(dǎo)航

和現(xiàn)在QQ類似導(dǎo)航

1·安裝
npm install @react-navigation/drawer

代碼演示

import 'react-native-gesture-handler';
import React, { Component } from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { createDrawerNavigator } from '@react-navigation/drawer';
import DetailsScreen from './DetailsScreen';
import HomeScreen from './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={DetailsScreen} />
      </Drawer.Navigator>
    </NavigationContainer>
  );
}

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

相關(guān)閱讀更多精彩內(nèi)容

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