材質頂部標籤導覽器
一種材質設計主題的標籤列,會顯示在螢幕上方,透過點擊標籤或水平滑動,即可在不同的路線間切換。預設會以動畫方式進行轉場。每個路線的畫面元件會立即掛載。
這會包覆 react-native-tab-view
。如果您想在沒有 React 導覽器整合的情況下使用標籤檢視,請改為直接使用函式庫。
安裝
要使用此導覽器,請確定您已有 @react-navigation/native
及其依賴項(依照本指南進行操作),然後安裝 @react-navigation/material-top-tabs
- npm
- Yarn
- pnpm
npm install @react-navigation/material-top-tabs react-native-tab-view
yarn add @react-navigation/material-top-tabs react-native-tab-view
pnpm add @react-navigation/material-top-tabs react-native-tab-view
然後,您需要安裝 react-native-pager-view
,這是導覽器所需的項目。
如果您使用的是 Expo 管理專案,請在專案目錄中執行
npx expo install react-native-pager-view
如果您使用的是純粹的 React Native 專案,請在專案目錄中執行
- npm
- Yarn
- pnpm
npm install react-native-pager-view
yarn add react-native-pager-view
pnpm add react-native-pager-view
如果您使用 Mac 並針對 iOS 進行開發,您也需要安裝 pod 組件(透過 Cocoapods),才能完成連結。
npx pod-install ios
API 定義
要使用此標籤導覽器,請從 @react-navigation/material-top-tabs
匯入
import { createMaterialTopTabNavigator } from '@react-navigation/material-top-tabs';
const Tab = createMaterialTopTabNavigator();
function MyTabs() {
return (
<Tab.Navigator>
<Tab.Screen name="Home" component={HomeScreen} />
<Tab.Screen name="Settings" component={SettingsScreen} />
</Tab.Navigator>
);
}
如需完整的用途指南,請瀏覽 標籤導覽
屬性
Tab.Navigator
元件接受下列屬性
id
導覽器的選用獨特 ID。這可搭配 navigation.getParent
在子導覽器中參考此導覽器。
initialRouteName
在第一次載入導覽器時要呈現的路徑名稱。
screenOptions
要在導覽器中用於畫面預設的選項。
backBehavior
這會控制在導覽器中呼叫 goBack
時的行為。其中包括在 Android 裝置上按下實體返回按鈕或執行返回手勢。
支援下列值
firstRoute
- 返回到導覽器定義的第一個畫面 (預設)initialRoute
- 返回到在initialRouteName
屬性中傳遞的初始畫面,如果未傳遞,則預設為第一個畫面order
- 返回到在焦點畫面之前的畫面history
- 返回到導覽器中最後瀏覽過的畫面;如果重複瀏覽同一個畫面,較舊的記錄會從歷程記錄中移除none
- 無法處理返回按鈕
tabBarPosition
標籤檢視中標籤列的位置。可能的值包括 'top'
和 'bottom'
。預設為 'top'
。
keyboardDismissMode
字串表示鍵盤會在拖曳手勢下消失。可能的值包括
'auto'
(預設):在索引改變時會讓鍵盤消失。'on-drag'
:在拖曳開始時會讓鍵盤消失。'none'
:拖曳不會讓鍵盤消失。
initialLayout
包含螢幕的初始高度和寬度的物件。傳遞這個值將改善初始整理的效能。對大部分的應用程式來說,這是一個好的預設值。
{
width: Dimensions.get('window').width;
}
sceneContainerStyle
對包裹每個螢幕的畫面套用的樣式。您可以傳遞此參數以覆寫部分預設樣式,例如溢位裁切。
style
對標籤畫面容器套用的樣式。
tabBar
傳回 React 元素作為標籤列顯示的函示。
範例
import { Animated, View, TouchableOpacity } from 'react-native';
function MyTabBar({ state, descriptors, navigation, position }) {
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,
});
};
const inputRange = state.routes.map((_, i) => i);
const opacity = position.interpolate({
inputRange,
outputRange: inputRange.map(i => (i === index ? 1 : 0)),
});
return (
<TouchableOpacity
accessibilityRole="button"
accessibilityState={isFocused ? { selected: true } : {}}
accessibilityLabel={options.tabBarAccessibilityLabel}
testID={options.tabBarTestID}
onPress={onPress}
onLongPress={onLongPress}
style={{ flex: 1 }}
>
<Animated.Text style={{ opacity }}>
{label}
</Animated.Text>
</TouchableOpacity>
);
})}
</View>
);
}
// ...
<Tab.Navigator tabBar={props => <MyTabBar {...props} />}>
{...}
</Tab.Navigator>
這個範例將整理出一個標籤有標題的基本標籤列。
請注意,由於 useNavigation 只能在螢幕內使用,因此您不能在 tabBar
內使用 useNavigation
鉤子。您可以取得 tabBar
的 navigation
prop,並用它來取代
function MyTabBar({ navigation }) {
return (
<Button
title="Go somewhere"
onPress={() => {
// Navigate using the `navigation` prop that you received
navigation.navigate('SomeScreen');
}}
/>
);
}
選項
下列選項可用於設定導覽器中的畫面
範例
<Tab.Navigator
screenOptions={{
tabBarLabelStyle: { fontSize: 12 },
tabBarItemStyle: { width: 100 },
tabBarStyle: { backgroundColor: 'powderblue' },
}}
>
{/* ... */}
</Tab.Navigator>
title
可作為 headerTitle
和 tabBarLabel
替補方案使用的一般標題。
tabBarLabel
顯示在標籤列中的標籤字串,或是一個給定 { focused: boolean, color: string }
後傳回 React.Node 以在標籤列顯示的函示。未定義時,將使用場景 title
。若要隱藏,請參閱tabBarShowLabel
選項。
tabBarAccessibilityLabel
標籤按鈕的可協助使用標籤。這會在使用者點選標籤時由螢幕朗讀器讀出。如果你沒有標籤供標籤使用,建議設定這個值。
tabBarAllowFontScaling
標籤字型是否應縮放以遵循文字大小的可協助使用設定。
tabBarShowLabel
標籤標籤是否應該可見。預設為 true
。
tabBarIcon
給定 { focused: boolean, color: string }
後傳回 React.Node 以在標籤列顯示的函示。
tabBarShowIcon
是否要顯示 tab 圖示。預設為 false
。
tabBarBadge
用作 tab 徽章的 React 元素回傳函數。
tabBarIndicator
用作 tab 列指標的 React 元素回傳函數。
tabBarIndicatorStyle
tab 列指標樣式物件。
tabBarIndicatorContainerStyle
包含 tab 列指標檢視的樣式物件。
tabBarTestID
在測試中找到此 tab 按鈕的 ID。
tabBarActiveTintColor
在作用中的 tab 列中,圖示和標籤的顏色。
tabBarInactiveTintColor
在未作用的 tab 列中,圖示和標籤的顏色。
tabBarGap
tab 列中 tab 項目之間的間距。
範例
<Tab.Navigator
//...
screenOptions={{
tabBarGap: 10,
}}
></Tab.Navigator>
tabBarAndroidRipple
允許自訂 Android 的漣漪效果。
範例
<Tab.Navigator
//...
screenOptions={{
tabBarAndroidRipple: { borderless: false },
}}
></Tab.Navigator>
tabBarPressColor
材料漣漪的顏色。
僅支援 Android。
tabBarPressOpacity
按下 tab 的不透明度。
僅支援 iOS。
tabBarBounces
布林值指示在捲動過頭時,tab 列是否彈跳。
tabBarScrollEnabled
布林值指示是否讓 tab 列可捲動。
如果你將此設定為 true
,也應該在 tabBarItemStyle
中指定寬度,以提升初始呈現的效能。
tabBarIconStyle
tab 圖示容器的樣式物件。
tabBarLabelStyle
標籤標籤的樣式物件。
tabBarItemStyle
個別標籤項目之樣式物件。
tabBarContentContainerStyle
包含標籤項目的檢視之樣式物件。
tabBarStyle
標籤列之樣式物件。
swipeEnabled
布林值表示是否要啟用滑動手勢。滑動手勢預設為啟用。傳遞 false
會停用滑動手勢,但使用者仍可按壓標籤列來切換標籤頁。
lazy
此畫面是否應延遲呈現。當此設定為 true
時,畫面會在進入視窗時才進行呈現。預設所有畫面都會進行呈現以提供更平順的滑動體驗。但是您可能想要延後呈現視窗外畫面,直到使用者看到這些畫面為止。要為此畫面啟用延遲呈現,請將 lazy
設定為 true
。
當您啟用 lazy
時,延遲載入的畫面通常會在進入視窗時花一些時間進行呈現。您可使用 lazyPlaceholder
屬性自訂使用者在此段時間中看到的畫面。
lazyPreloadDistance
當啟用 lazy
時,您可以透過此屬性指定預先載入相鄰畫面的數量。此值的預設為 0
,這表示延遲載入畫面會在進入視窗時進行載入。
lazyPlaceholder
如果此畫面尚未呈現的 React 元素之回傳函數。此畫面也需要啟用 lazy
選項才能運作。
此檢視通常只會顯示一瞬間。請予以簡要。
預設會呈現 null
。
事件
Navigator 可在特定動作中發出事件。以下是支援的事件
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]);
輔助工具
標籤導航器會將下列方法新增到導航屬性
jumpTo
導覽至標籤導航器中的現有畫面。此方法接受下列引數
name
- 字串 - 要跳轉到的路徑名稱。params
- 物件 - 傳遞至目標路徑的畫面參數。
navigation.jumpTo('Profile', { name: 'Michaś' });
範例
import { createMaterialTopTabNavigator } from '@react-navigation/material-top-tabs';
const Tab = createMaterialTopTabNavigator();
function MyTabs() {
return (
<Tab.Navigator
initialRouteName="Feed"
screenOptions={{
tabBarActiveTintColor: '#e91e63',
tabBarLabelStyle: { fontSize: 12 },
tabBarStyle: { backgroundColor: 'powderblue' },
}}
>
<Tab.Screen
name="Feed"
component={Feed}
options={{ tabBarLabel: 'Home' }}
/>
<Tab.Screen
name="Notifications"
component={Notifications}
options={{ tabBarLabel: 'Updates' }}
/>
<Tab.Screen
name="Profile"
component={Profile}
options={{ tabBarLabel: 'Profile' }}
/>
</Tab.Navigator>
);
}