跳至主要內容
版本:6.x

Drawer Navigator

Drawer Navigator 會在畫面的側邊呈現一個可透過手勢開啟和關閉的導覽抽屜。

這是包裝的 react-native-drawer-layout。如果您想在沒有 React Navigation 整合的狀況下使用抽屜,請直接使用該函式庫。

安裝

要使用此瀏覽器,請確定您已安裝 @react-navigation/native 及其相依性項(請參閱本指南),然後安裝 @react-navigation/drawer

npm install @react-navigation/drawer

接著,您需要安裝並設定抽屜瀏覽器所需的函式庫

  1. 首先,安裝 react-native-gesture-handlerreact-native-reanimated

    如果您執行的是 Expo 管理的專案,請在您的專案目錄中執行

    npx expo install react-native-gesture-handler react-native-reanimated

    如果您執行的是裸露 React Native 專案,請在您的專案目錄中執行

    npm install react-native-gesture-handler react-native-reanimated

    Drawer 支援 Reanimated 1 和最新版本的 Reanimated。如果您想使用最新版本的 Reanimated,請務必按照 安裝指南 設定。

  2. 要完成安裝 react-native-gesture-handler,請在您的入口檔案(例如 index.jsApp.js)的最上方加入下述程式碼(請確認它是最上方的程式碼,且前面沒有其他內容)

    import 'react-native-gesture-handler';
    警告

    如果您為 Android 或 iOS 進行建構,請不要跳過此步驟,否則您的應用程式即使在開發階段執行良好,也可能會在實際環境中崩潰。此步驟不適用於其他平台。

  3. 如果您使用 Mac 並開發 iOS,您還需要安裝 pods(透過 Cocoapods)才能完成連結。

npx pod-install ios

API 定義

若要使用此抽屜導覽,請從 @react-navigation/drawer 匯入

import { createDrawerNavigator } from '@react-navigation/drawer';

const Drawer = createDrawerNavigator();

function MyDrawer() {
return (
<Drawer.Navigator>
<Drawer.Screen name="Feed" component={Feed} />
<Drawer.Screen name="Article" component={Article} />
</Drawer.Navigator>
);
}
說明

如需完整的使用指南,請參閱 抽屜導覽

Props

Drawer.Navigator 元件接受下列道具

id

導覽的選用唯一 ID。這可以與 navigation.getParent 搭配使用,在子導覽中參考此導覽。

initialRouteName

在導覽首次載入時要呈現的路線名稱。

screenOptions

導覽中畫面要使用的預設選項。

backBehavior

當在導覽中呼叫 goBack 時,由其控制後續動作。包含按下 Android 裝置上的返回鍵或返回手勢。

它支援下列值

  • firstRoute - 回到導覽中定義的第一個畫面(預設)
  • initialRoute - 如果未傳遞,則返回傳入 initialRouteName 道具中的初始畫面,否則使用第一個畫面
  • order - 返回聚焦畫面之前的已定義畫面
  • history - 返回導覽器中最後一次瀏覽的畫面;如果多次瀏覽同一畫面,則會從歷史記錄中刪除較舊的項目
  • none - 不處理返回按鈕

defaultStatus

櫃子的預設狀態 - 預設情況下櫃子是要維持 開啟 還是 關閉 狀態。

當此設定設為 開啟 時,櫃子會從初始呈現開始開啟。通常可以使用手勢或以程式方式將它關閉。但是,當返回時,如果櫃子是關閉的,則會重新開啟。這基本上與櫃子的預設行為相反,在預設行為中,櫃子會從 關閉 開始,返回按鈕會將開啟的櫃子關閉。

detachInactiveScreens

布林值,用來表示是否要從檢視階層中分離非作用中的畫面,以節省記憶體。這能與 react-native-screens 進行整合。預設為 true

useLegacyImplementation

是否要使用基於 Reanimated 1 的舊版實作。基於 Reanimated 2 的新實作效能會更好,但你需要額外設定,並且需要與 Flipper 搭配使用 Hermes 進行除錯。

在下列情況下,此設定預設為 true

  • 未設定 Reanimated 2
  • 應用程式已連線至 Chrome 除錯程式(Reanimated 2 無法與 Chrome 除錯程式搭配使用)
  • 應用程式在 Web 上執行

否則,預設為 false

drawerContent

傳回要呈現為櫃子內容的 React 元件的函式,例如,導覽項目

內容元件預設接收下列道具

  • state - 導覽器的 導覽狀態
  • navigation - 導覽器的導覽物件。
  • descriptors - 包含抽屜畫面的選項的描述元件物件。可以在 descriptors[route.key].options 中存取這些選項。
提供自訂的 drawerContent

抽屜的預設元件可捲動且只包含路由配置中路由的連結。您可以輕鬆覆寫預設元件為抽屜新增標題、頁尾或其他內容。預設內容元件以 DrawerContent 匯出。它會在 ScrollView 中繪製 DrawerItemList 元件。

預設情況下,抽屜是可滾動的,支援帶有缺口的裝置。如果您自訂內容,可以使用 DrawerContentScrollView 自動執行此操作

import {
DrawerContentScrollView,
DrawerItemList,
} from '@react-navigation/drawer';

function CustomDrawerContent(props) {
return (
<DrawerContentScrollView {...props}>
<DrawerItemList {...props} />
</DrawerContentScrollView>
);
}

若要新增額外的項目至抽屜中,您可以使用 DrawerItem 元件

function CustomDrawerContent(props) {
return (
<DrawerContentScrollView {...props}>
<DrawerItemList {...props} />
<DrawerItem
label="Help"
onPress={() => Linking.openURL('https://mywebsite.com/help')}
/>
</DrawerContentScrollView>
);
}

DrawerItem 元件接受下列道具

  • label(必填):項目的標籤文字。可以是字串,或是傳回 React 元素的函式。例如:({ focused, color }) => <Text style={{ color }}>{focused ? 'Focused text' : 'Unfocused text'}</Text>
  • icon:要為項目顯示的圖示。接受傳回 React 元素的函式。例如:({ focused, color, size }) => <Icon color={color} size={size} name={focused ? 'heart' : 'heart-outline'} />
  • focused:布林值,用來指示是否要將抽屜項目標示為「活動」。
  • onPress(必填):按下時執行之函式。
  • activeTintColor:項目處於「活動」狀態時的圖示和標籤顏色。
  • inactiveTintColor:項目處於「非活動」狀態時的圖示和標籤顏色。
  • activeBackgroundColor:項目處於「活動」狀態時的背景顏色。
  • inactiveBackgroundColor:項目處於「非活動」狀態時的背景顏色。
  • labelStyle:標籤 文字 的樣式物件。
  • style:包裝 檢視 的樣式物件。

progress 物件可用於在您的 drawerContent 中執行有趣的動態效果,例如抽屜內容視差移動

function CustomDrawerContent(props) {
const progress = useDrawerProgress();

// If you are on react-native-reanimated 1.x, use `Animated.interpolate` instead of `Animated.interpolateNode`
const translateX = Animated.interpolateNode(progress, {
inputRange: [0, 1],
outputRange: [-100, 0],
});

return (
<Animated.View style={{ transform: [{ translateX }] }}>
{/* ... drawer contents */}
</Animated.View>
);
}

如果您使用 Reanimated 1(請參閱 useLegacyImplementation),progress 物件是 Reanimated 節點;否則,它是一個 共用值。它表示抽屜的動態位置(0 為關閉;1 為開啟)。

請注意,您無法drawerContent 內部使用 useNavigation 掛鉤,因為 useNavigation 只在畫面中才可用。您會取得 drawerContentnavigation 道具,您可以使用此道具

function CustomDrawerContent({ navigation }) {
return (
<Button
title="Go somewhere"
onPress={() => {
// Navigate using the `navigation` prop that you received
navigation.navigate('SomeScreen');
}}
/>
);
}

若要使用自訂元件,我們需要將它傳入 drawerContent 道具

<Drawer.Navigator drawerContent={(props) => <CustomDrawerContent {...props} />}>
{/* screens */}
</Drawer.Navigator>

選項

可以使用下列 選項 來設定導航員的畫面。可以在 Drawer.navigatorscreenOptions 道具或 Drawer.Screenoptions 道具下指定這些選項。

title

可用作 headerTitledrawerLabel 備援的通用標題。

lazy

這個畫面第一次被存取時是否應呈現。預設為 true。如果您要在初始呈現時呈現畫面,請將它設為 false

drawerLabel

字串或函式,給定 { focused: boolean, color: string } 後會傳回 React.Node,以在抽屜側欄中顯示。未定義時,會使用場景 title

drawerIcon

函式,給定 { focused: boolean, color: string, size: number } 後會傳回 React.Node,以在抽屜側欄中顯示。

drawerActiveTintColor

抽屜中活躍選項的圖示與標籤顏色。

drawerActiveBackgroundColor

抽屜中活躍選項的背景顏色。

drawerInactiveTintColor

抽屜中未活躍選項的圖示與標籤顏色。

drawerInactiveBackgroundColor

抽屜中未活躍選項的背景顏色。

drawerItemStyle

單一選項的樣式物件,可能包含圖示和/或標籤。

drawerLabelStyle

樣式物件,用於套用在內容區段內的 Text 樣式,此區段會呈現標籤。

drawerContentContainerStyle

ScrollView 內部內容區段的樣式物件。

drawerContentStyle

封裝檢視的樣式物件。

drawerStyle

抽屜元件的樣式物件。您可以在此輸入抽屜的自訂背景顏色或自訂寬度。

<Drawer.Navigator
screenOptions={{
drawerStyle: {
backgroundColor: '#c6cbef',
width: 240,
},
}}
>
{/* screens */}
</Drawer.Navigator>

drawerPosition

選項為 leftright。LTR 語言預設為 left,RTL 語言預設為 right

drawerType

抽屜的類型。它決定抽屜的外觀和動畫。

  • front:傳統抽屜,其覆蓋屏幕,並在屏幕後方顯示一個圖層。
  • back:在滑動時顯示屏幕後方的抽屜。
  • slide:在滑動時,同時滑動屏幕和抽屜,以顯示抽屜。
  • permanent:永久抽屜顯示為側邊欄。對於大屏幕上始終顯示抽屜來說非常有用。

預設值:iOS上的slide,其他平台的front

您可以有條件地指定drawerType,以在大屏幕上顯示永久抽屜,而在小屏幕上顯示傳統抽屜。

import { useWindowDimensions } from 'react-native';
import { createDrawerNavigator } from '@react-navigation/drawer';

const Drawer = createDrawerNavigator();

function MyDrawer() {
const dimensions = useWindowDimensions();

return (
<Drawer.Navigator
screenOptions={{
drawerType: dimensions.width >= 768 ? 'permanent' : 'front',
}}
>
{/* Screens */}
</Drawer.Navigator>
);
}

您也可以根據屏幕尺寸指定其他屬性,例如drawerStyle,以自訂行為。例如,您可以將其與defaultStatus="open"結合起來,以形成主從布局。

import { useWindowDimensions } from 'react-native';
import { createDrawerNavigator } from '@react-navigation/drawer';

const Drawer = createDrawerNavigator();

function MyDrawer() {
const dimensions = useWindowDimensions();

const isLargeScreen = dimensions.width >= 768;

return (
<Drawer.Navigator
defaultStatus="open"
screenOptions={{
drawerType: isLargeScreen ? 'permanent' : 'back',
drawerStyle: isLargeScreen ? null : { width: '100%' },
overlayColor: 'transparent',
}}
>
{/* Screens */}
</Drawer.Navigator>
);
}

drawerHideStatusBarOnOpen

設定為true時,抽屜會在拉出時或為「開啟」狀態時隱藏作業系統狀態欄。

drawerStatusBarAnimation

隱藏狀態欄時的動畫。與hideStatusBar結合使用。

支援的值

  • slide
  • fade
  • none

這僅在 iOS 上支援。預設值為slide

overlayColor

開啟抽屜時顯示在內容檢視上方顏色的圖層。開啟抽屜時,不透明度從0動畫至1

sceneContainerStyle

包裝屏幕內容的元件的樣式物件。

gestureHandlerProps

要傳遞給基礎平移手勢處理常式的屬性。

此功能在 Web 上不受支援。

swipeEnabled

是否可以使用滑動手勢開啟或關閉抽屜。預設值為true

Web 上不支援滑動手勢。

swipeEdgeWidth

定義滑動手勢應從內容檢視邊緣何處開始觸發。

此功能在 Web 上不受支援。

swipeMinDistance

開啟抽屜所需的最小滑動距離閾值。

keyboardDismissMode

滑動手勢開始時,是否應關閉鍵盤。預設為 'on-drag'。設為 'none' 以停用鍵盤處理。

unmountOnBlur

遠離畫面時,此畫面是否應卸載。卸載畫面會重設畫面中的任何本機狀態,以及畫面中嵌套導航器的狀態。預設為 false

通常,我們不建議啟用此項屬性,因為使用者不希望在切換畫面時他們的瀏覽記錄消失。如果你啟用此項屬性,請考慮這是否確實能為使用者提供更好的體驗。

freezeOnBlur

布林值,代表是否要阻止非活動畫面重新呈現。預設為 false。當應用程式頂端執行 react-native-screens 套件的 enableFreeze() 時,預設為 true

需要 react-native-screens 版本 >= 3.16.0。

僅支援 iOS 和 Android。

你可以在 此處 找到標頭相關選項清單。這些 選項 可以在 Drawer.navigatorscreenOptions 屬性或 Drawer.Screenoptions 屬性中指定。你無需直接使用 @react-navigation/elements 就能使用這些選項,它們只是在那個頁面中做了文件說明。

除此之外,抽屜中也支援下列選項

自訂標頭,用來取代預設的標頭。

此項選項接受回傳 React 元素的函數作為參數,以顯示為標頭。函數會接收一個物件,其中包含下列屬性

  • navigation - 目前畫面的導航物件。
  • route - 目前畫面的路由物件。
  • options - 目前畫面的選項
  • layout - 畫面的尺寸,包含 heightwidth 屬性。

範例

import { getHeaderTitle } from '@react-navigation/elements';

// ..

header: ({ navigation, route, options }) => {
const title = getHeaderTitle(options, route.name);

return <MyHeader title={title} style={options.headerStyle} />;
};

要在導航器中的所有畫面設定自訂標頭,你可以在導航器的 screenOptions 屬性中指定此選項。

headerStyle 中指定 height

如果你的自訂標頭高度與預設標頭高度不同,你可能會因為測量為非同步而看到一些錯誤。明確指定高度將可以避免此類錯誤。

範例

headerStyle: {
height: 80, // Specify the height of your custom header
};

請注意,此樣式預設並未套用至標頭,因為你控制的是自訂標頭的樣式。如果你還要將此樣式套用至你的標頭,請使用屬性中的 options.headerStyle

headerShown

是否要顯示或隱藏畫面的標頭。預設會顯示標頭。如果將它設定為 false,則隱藏標頭。

事件

導覽器可以在特定動作時發出事件。支援的事件包括

drawerItemPress

當使用者在抽屜中按下畫面按鈕時,會引發這個事件。預設在按下抽屜項目時,會有幾種動作

  • 如果畫面沒有獲得焦點,按下抽屜項目會讓該畫面獲得焦點
  • 如果畫面已經獲得焦點,則會關閉抽屜

要避免預設行為,你可以呼叫 event.preventDefault

React.useEffect(() => {
const unsubscribe = navigation.addListener('drawerItemPress', (e) => {
// Prevent default behavior
e.preventDefault();

// Do something manually
// ...
});

return unsubscribe;
}, [navigation]);

如果你的抽屜內容是自訂的,請確定要發出這個事件。

輔助函式

抽屜導覽器將以下方法新增到導覽 props

openDrawer

開啟抽屜窗格。

navigation.openDrawer();

closeDrawer

關閉抽屜窗格。

navigation.closeDrawer();

toggleDrawer

如果抽屜已關閉,則開啟抽屜窗格,如果已開啟,則關閉抽屜窗格。

navigation.toggleDrawer();

jumpTo

在抽屜導覽器中導覽到現有的畫面。這個方法會接受下列引數

  • name - 字串 - 要跳轉到的路由名稱。
  • params - 物件 - 要傳遞到目的路由的畫面參數。
navigation.jumpTo('Profile', { owner: 'Satya' });

範例

import { createDrawerNavigator } from '@react-navigation/drawer';

const Drawer = createDrawerNavigator();

function MyDrawer() {
return (
<Drawer.Navigator initialRouteName="Feed">
<Drawer.Screen
name="Feed"
component={Feed}
options={{ drawerLabel: 'Home' }}
/>
<Drawer.Screen
name="Notifications"
component={Notifications}
options={{ drawerLabel: 'Updates' }}
/>
<Drawer.Screen
name="Profile"
component={Profile}
options={{ drawerLabel: 'Profile' }}
/>
</Drawer.Navigator>
);
}

檢查抽屜是否開啟

你可以使用 useDrawerStatus 勾子來檢查抽屜是否開啟。

import { useDrawerStatus } from '@react-navigation/drawer';

// ...

const isDrawerOpen = useDrawerStatus() === 'open';

如果你無法使用此勾子,你也可以使用 getDrawerStatusFromState 輔助函式

import { getDrawerStatusFromState } from '@react-navigation/drawer';

// ...

const isDrawerOpen = getDrawerStatusFromState(navigation.getState()) === 'open';

對於類別元件,你可以聆聽 state 事件來檢查抽屜是否開啟或關閉

class Profile extends React.Component {
componentDidMount() {
this._unsubscribe = navigation.addListener('state', () => {
const isDrawerOpen =
getDrawerStatusFromState(navigation.getState()) === 'open';

// do something
});
}

componentWillUnmount() {
this._unsubscribe();
}

render() {
// Content of the component
}
}

將抽屜導覽器嵌套在其他元件中

如果一個抽屜導航嵌套在另外提供一些 UI 的導航中,例如一個分頁導航或堆疊導航,那麼這個抽屜會呈現在這些導航的 UI 之下。抽屜會顯示在分頁標籤下方和堆疊標題下方。您需要讓抽屜導航成為任何導航的父層,讓抽屜顯示在它的 UI 的上方。