下方分頁導覽列
在螢幕下方顯示一個簡易分頁工具列,讓您可以在不同的路由之間切換。路由會使用惰性初始化,因此其螢幕組件在第一次被聚焦時才會載入。
安裝
如要使用此導覽列,請務必安裝@react-navigation/native
及其依賴項(按照此指南),然後安裝@react-navigation/bottom-tabs
- npm
- Yarn
- pnpm
npm install @react-navigation/bottom-tabs
yarn add @react-navigation/bottom-tabs
pnpm add @react-navigation/bottom-tabs
API 定義
如要使用此分頁導覽列,請從@react-navigation/bottom-tabs
匯入
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
const Tab = createBottomTabNavigator();
function MyTabs() {
return (
<Tab.Navigator>
<Tab.Screen name="Home" component={HomeScreen} />
<Tab.Screen name="Settings" component={SettingsScreen} />
</Tab.Navigator>
);
}
如需完整的用法指南,請參閱分頁式導覽列
屬性
Tab.Navigator
組件接受下列屬性
id
導航器的選用式唯一識別碼。這可以用於 navigation.getParent
來在子導航器中參考這個導航器。
initialRouteName
在導航器第一次載入之後要呈現路由的名稱。
screenOptions
在導航器的畫面中要使用的預設選項。
backBehavior
在導航器呼叫 goBack
之後,它會控制有什麼事情會發生。這包括按 Android 裝置的返回按鍵或返回手勢。
它支援下列值
firstRoute
- 回到導航器中定義的第一個畫面(預設)initialRoute
- 回到initialRouteName
屬性中傳遞的初始畫面,如果沒有傳遞,預設為第一個畫面order
- 回到在焦點畫面之前的定義畫面history
- 回到導航器中上次瀏覽的畫面;如果同一畫面被瀏覽多次,較舊的項目將會從紀錄中被移除none
- 不要處理返回按鈕
detachInactiveScreens
布林值,用於指示是否應該將非作用中的畫面從檢視階層中分離以節省記憶體。這允許與 react-native-screens 整合。預設為 true
。
sceneContainerStyle
包覆畫面內容的組件樣式物件。
tabBar
做為標籤列顯示的 React 元素的函式。
範例
import { View, Text, TouchableOpacity } from 'react-native';
function MyTabBar({ state, descriptors, navigation }) {
return (
<View style={{ flexDirection: 'row' }}>
{state.routes.map((route, index) => {
const { options } = descriptors[route.key];
const label =
options.tabBarLabel !== undefined
? options.tabBarLabel
: options.title !== undefined
? options.title
: route.name;
const isFocused = state.index === index;
const onPress = () => {
const event = navigation.emit({
type: 'tabPress',
target: route.key,
canPreventDefault: true,
});
if (!isFocused && !event.defaultPrevented) {
navigation.navigate(route.name, route.params);
}
};
const onLongPress = () => {
navigation.emit({
type: 'tabLongPress',
target: route.key,
});
};
return (
<TouchableOpacity
accessibilityRole="button"
accessibilityState={isFocused ? { selected: true } : {}}
accessibilityLabel={options.tabBarAccessibilityLabel}
testID={options.tabBarTestID}
onPress={onPress}
onLongPress={onLongPress}
style={{ flex: 1 }}
>
<Text style={{ color: isFocused ? '#673ab7' : '#222' }}>
{label}
</Text>
</TouchableOpacity>
);
})}
</View>
);
}
// ...
<Tab.Navigator tabBar={props => <MyTabBar {...props} />}>
{...}
</Tab.Navigator>
這個範例會呈現一個標籤上有標籤的基本標籤列。
請注意你不能在 tabBar
中使用 useNavigation
勾子,因為 useNavigation
只能在畫面中使用。你會獲得一個 tabBar
的 navigation
屬性,你可以改用它
function MyTabBar({ navigation }) {
return (
<Button
title="Go somewhere"
onPress={() => {
// Navigate using the `navigation` prop that you received
navigation.navigate('SomeScreen');
}}
/>
);
}
選項
下列 選項 可用於設定導航器中的畫面。可以在 Tab.navigator
的 screenOptions
屬性或 Tab.Screen
的 options
屬性下指定這些選項。
title
可作為 headerTitle
和 tabBarLabel
備援的通用標題。
tabBarLabel
在標籤列中顯示的標籤標題字串或是一個函式,提供 { focused: boolean, color: string }
之後傳回 React.Node 在標籤列中顯示。未定義時會使用場景 title
。若要隱藏,請見 tabBarShowLabel
。
tabBarShowLabel
標籤標籤是否應該可見。預設為 true
。
tabBarLabelPosition
標籤於圖示下方或圖示旁邊顯示。
below-icon
:標籤顯示在圖示下方(如 iPhone)beside-icon
標籤顯示在圖示旁邊(如 iPad)
預設位置會根據裝置寬度自動選取。
tabBarLabelStyle
標籤標籤的樣式物件。
tabBarIcon
在標籤列中顯示一個函式,提供 { focused: boolean, color: string, size: number }
之後傳回 React.Node。
tabBarIconStyle
標籤圖示的樣式物件。
tabBarBadge
在標籤圖示上以徽章顯示的文字。接受 string
或 number
。
tabBarBadgeStyle
標籤圖示上徽章的樣式。您可以在此處指定背景色彩或文字色彩。
tabBarAccessibilityLabel
標籤按鈕的可存取性標籤。當使用者點選標籤時,螢幕閱讀器會讀取此標籤。如果您沒有標籤標籤,建議設定這項功能。
tabBarTestID
在測試中找出此標籤按鈕的 ID。
tabBarButton
傳回 React 元素的函式,用以標籤按鈕顯示。預設會包裝圖示和標籤。預設顯示 Pressable
。
您可以在此處指定自訂實作
tabBarButton: (props) => <TouchableOpacity {...props} />;
tabBarActiveTintColor
作用中標籤頁中的圖示和標籤的顏色。
tabBarInactiveTintColor
作用中標籤頁的圖示和標籤的顏色。
tabBarActiveBackgroundColor
作用中標籤頁的背景顏色。
tabBarInactiveBackgroundColor
非作用中標籤頁的背景顏色。
tabBarHideOnKeyboard
當鍵盤開啟時,標籤頁列是否隱藏。預設值為 false
。
tabBarItemStyle
標籤頁項目容器的樣式物件。
tabBarStyle
標籤頁列的樣式物件。您可以在這裡設定樣式,例如背景顏色。
若要於標籤頁列下方顯示螢幕,您可以將 position
樣式設定為絕對
<Tab.Navigator
screenOptions={{
tabBarStyle: { position: 'absolute' },
}}
>
如果您有絕對定位的標籤頁列,可能也需要為內容新增底端距離。React 導覽不會自動執行此動作。
若要取得底端標籤頁列的高度,您可以搭配 React 的 Context API 使用 BottomTabBarHeightContext
或 useBottomTabBarHeight
import { BottomTabBarHeightContext } from '@react-navigation/bottom-tabs';
// ...
<BottomTabBarHeightContext.Consumer>
{tabBarHeight => (
/* render something */
)}
</BottomTabBarHeightContext.Consumer>
或
import { useBottomTabBarHeight } from '@react-navigation/bottom-tabs';
// ...
const tabBarHeight = useBottomTabBarHeight();
tabBarBackground
用於傳回 React 元素作為標籤頁列背景的函式。您可以選擇顯示圖片、漸層、模糊視圖等等。
import { BlurView } from 'expo-blur';
// ...
<Tab.Navigator
screenOptions={{
tabBarStyle: { position: 'absolute' },
tabBarBackground: () => (
<BlurView tint="light" intensity={100} style={StyleSheet.absoluteFill} />
),
}}
>
使用 BlurView
時,請務必也在 tabBarStyle
中設定 position: 'absolute'
。您還需要使用 useBottomTabBarHeight()
為內容新增底端間距。
lazy
此螢幕在第一次存取時是否應該顯示。預設值為 true
。如果您想要在最初顯示時就顯示螢幕,請將其設定為 false
。
unmountOnBlur
離開此畫面時,此畫面是否應該解除安裝。解除安裝畫面會重設畫面中的所有區域狀態以及畫面中巢狀導覽器的狀態。預設值為 false
。
一般來說,我們不建議啟用此屬性,因為使用者在切換標籤頁時不期望導覽記錄會消失。如果您要啟用此屬性,請先想想這是否實際上能為使用者提供更好的體驗。
freezeOnBlur
布林值,表示是否防止非活動畫面再次渲染。預設為 false
。在應用程式頂端執行 react-native-screens
套件的 enableFreeze()
時,預設為 true
。
需要 react-native-screens
版本 >=3.16.0。
僅支援 iOS 和 Android。
標題相關選項
您可以在 這裡 找到標題相關選項清單。這些 選項 可以指定在 Tab.navigator
的 screenOptions
屬性或 Tab.Screen
的 options
屬性下。您不必直接使用 @react-navigation/elements
來使用這些選項,它們只是記錄在該頁面中。
除了這些,底部分頁標籤中還支援下列選項
header
自訂標題,用於取代預設標題。
這會接受一個函式,傳回一個做為標題顯示的 React 元素。此函式接收一個包含下列屬性的物件作為參數
navigation
- 當前畫面的導覽物件。route
- 當前畫面的路由物件。options
- 當前畫面的選項layout
- 畫面的維度,包含height
和width
屬性。
範例
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
可隱藏標題。
事件
導覽器可在特定動作上 發出事件。支援的事件如下
tabPress
使用者在標籤列按下目前畫面標籤按鈕時會觸發此事件。預設標籤按鈕會執行多項動作
- 如果焦點不在該標籤,會將焦點移至該標籤
- 如果焦點已在該標籤
- 如果標籤的畫面會呈式捲動檢視,可以使用
useScrollToTop
將畫面捲動至頂端 - 如果標籤的畫面會呈式堆疊導航器,會對堆疊執行
popToTop
動作
- 如果標籤的畫面會呈式捲動檢視,可以使用
若要阻止預設行為,可以呼叫 event.preventDefault
React.useEffect(() => {
const unsubscribe = navigation.addListener('tabPress', (e) => {
// Prevent default behavior
e.preventDefault();
// Do something manually
// ...
});
return unsubscribe;
}, [navigation]);
如果你有自訂標籤列,記得發出此事件。
tabLongPress
當使用者長時間按下標籤列中目前畫面的標籤按鈕時,會觸發此事件。如果你有自訂標籤列,記得發出此事件。
範例
React.useEffect(() => {
const unsubscribe = navigation.addListener('tabLongPress', (e) => {
// Do something
});
return unsubscribe;
}, [navigation]);
幫手
標籤導航器會在導航器 prop 中新增下列方法
jumpTo
導覽至標籤導航器中現有的畫面。此方法會接受下列參數
name
- 字串 - 要導覽到的路由名稱。params
- 物件 - 目標路線要使用的畫面 params。
navigation.jumpTo('Profile', { owner: 'Michaś' });
範例
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons';
const Tab = createBottomTabNavigator();
function MyTabs() {
return (
<Tab.Navigator
initialRouteName="Feed"
screenOptions={{
tabBarActiveTintColor: '#e91e63',
}}
>
<Tab.Screen
name="Feed"
component={Feed}
options={{
tabBarLabel: 'Home',
tabBarIcon: ({ color, size }) => (
<MaterialCommunityIcons name="home" color={color} size={size} />
),
}}
/>
<Tab.Screen
name="Notifications"
component={Notifications}
options={{
tabBarLabel: 'Updates',
tabBarIcon: ({ color, size }) => (
<MaterialCommunityIcons name="bell" color={color} size={size} />
),
tabBarBadge: 3,
}}
/>
<Tab.Screen
name="Profile"
component={Profile}
options={{
tabBarLabel: 'Profile',
tabBarIcon: ({ color, size }) => (
<MaterialCommunityIcons name="account" color={color} size={size} />
),
}}
/>
</Tab.Navigator>
);
}