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

分頁導覽

分頁導覽可能是行動應用程式最常見的導覽樣式。分頁可能是位於畫面上方或下方(甚至取代標題)的標籤。

本指南包含 createBottomTabNavigator。你也可以使用 createMaterialBottomTabNavigatorcreateMaterialTopTabNavigator 在應用程式中新增分頁。

在繼續之前,請先安裝 @react-navigation/bottom-tabs

npm install @react-navigation/bottom-tabs

分頁導覽的最小範例

import * as React from 'react';
import { Text, View } from 'react-native';
import { NavigationContainer } from '@react-navigation/native';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';

function HomeScreen() {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Home!</Text>
</View>
);
}

function SettingsScreen() {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Settings!</Text>
</View>
);
}

const Tab = createBottomTabNavigator();

export default function App() {
return (
<NavigationContainer>
<Tab.Navigator>
<Tab.Screen name="Home" component={HomeScreen} />
<Tab.Screen name="Settings" component={SettingsScreen} />
</Tab.Navigator>
</NavigationContainer>
);
}

Tabs minimal

自訂外觀

這類似於如何自訂堆疊導覽器 - 在初始化分頁導覽器時,會設定一些屬性,而其他屬性則可以在 選項 中按畫面自訂。

// You can import Ionicons from @expo/vector-icons/Ionicons if you use Expo or
// react-native-vector-icons/Ionicons otherwise.
import Ionicons from 'react-native-vector-icons/Ionicons';

// (...)

export default function App() {
return (
<NavigationContainer>
<Tab.Navigator
screenOptions={({ route }) => ({
tabBarIcon: ({ focused, color, size }) => {
let iconName;

if (route.name === 'Home') {
iconName = focused
? 'ios-information-circle'
: 'ios-information-circle-outline';
} else if (route.name === 'Settings') {
iconName = focused ? 'ios-list' : 'ios-list-outline';
}

// You can return any component that you like here!
return <Ionicons name={iconName} size={size} color={color} />;
},
tabBarActiveTintColor: 'tomato',
tabBarInactiveTintColor: 'gray',
})}
>
<Tab.Screen name="Home" component={HomeScreen} />
<Tab.Screen name="Settings" component={SettingsScreen} />
</Tab.Navigator>
</NavigationContainer>
);
}

來分析一下

  • tabBarIcon 是底部分頁導覽器的支援選項。因此,我們知道可以在 選項 prop 中對我們的畫面元件使用它,但在這種情況下,選擇將它放在 Tab.NavigatorscreenOptions prop 中,以便集中管理圖示組態,以簡化操作。
  • tabBarIcon 是給予 focused 狀態、colorsize 參數的函數。如果深入查看組態,您會看到 tabBarActiveTintColortabBarInactiveTintColor。它們預設為 iOS 平台預設值,但您可以在這裡變更它們。傳遞給 tabBarIconcolor 是根據 focused 狀態(已聚焦為活動中)是為活動中還是非活動中的顏色。size 是分頁欄預期的圖示大小。
  • 閱讀 完整的 API 參考 以進一步瞭解 createBottomTabNavigator 組態選項。

在圖示上新增徽章

有時我們希望在某些圖示上新增徽章。您可以使用 tabBarBadge 選項 來執行這項工作

<Tab.Screen name="Home" component={HomeScreen} options={{ tabBarBadge: 3 }} />

從 UI 角度來看,此元件已準備好可以使用,但您仍需要找出某種方式,從其他地方正確傳遞徽章計數,例如使用 React ContextReduxMobX事件發射器

Tabs with badges

在分頁之間跳轉

從一個分頁切換到另一個分頁有熟悉的 API - navigation.navigate

function HomeScreen({ navigation }) {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Home!</Text>
<Button
title="Go to Settings"
onPress={() => navigation.navigate('Settings')}
/>
</View>
);
}

function SettingsScreen({ navigation }) {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Settings!</Text>
<Button title="Go to Home" onPress={() => navigation.navigate('Home')} />
</View>
);
}

每個分頁的堆疊導覽器

通常,分頁不會只顯示一個畫面 - 例如,在您的 Twitter 動態中,您可以輕觸推文,它會在分頁中帶您前往一個包含所有回覆的新畫面。您可以將此視為每個分頁中都有獨立的導覽堆疊,這正是我們將在 React 導覽中對其進行建模的方式。

import * as React from 'react';
import { Button, Text, View } from 'react-native';
import { NavigationContainer } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';

function DetailsScreen() {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Details!</Text>
</View>
);
}

function HomeScreen({ navigation }) {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Home screen</Text>
<Button
title="Go to Details"
onPress={() => navigation.navigate('Details')}
/>
</View>
);
}

function SettingsScreen({ navigation }) {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Settings screen</Text>
<Button
title="Go to Details"
onPress={() => navigation.navigate('Details')}
/>
</View>
);
}

const HomeStack = createNativeStackNavigator();

function HomeStackScreen() {
return (
<HomeStack.Navigator>
<HomeStack.Screen name="Home" component={HomeScreen} />
<HomeStack.Screen name="Details" component={DetailsScreen} />
</HomeStack.Navigator>
);
}

const SettingsStack = createNativeStackNavigator();

function SettingsStackScreen() {
return (
<SettingsStack.Navigator>
<SettingsStack.Screen name="Settings" component={SettingsScreen} />
<SettingsStack.Screen name="Details" component={DetailsScreen} />
</SettingsStack.Navigator>
);
}

const Tab = createBottomTabNavigator();

export default function App() {
return (
<NavigationContainer>
<Tab.Navigator screenOptions={{ headerShown: false }}>
<Tab.Screen name="HomeStack" component={HomeStackScreen} />
<Tab.Screen name="SettingsStack" component={SettingsStackScreen} />
</Tab.Navigator>
</NavigationContainer>
);
}

為什麼我們需要 TabNavigator,而不是 TabBarIOS 或其他元件?

許多人會嘗試使用獨立的標籤列元件,但沒有將它整合到 app 中所使用的導覽庫中。某些情況下,此作法並無不妥!不過我們在此要提醒您,這麼做可能會遇到一些令人沮喪且始料未及的問題。

舉例來說,React Navigation 的標籤導覽器會幫您處理 Android 的返回按鈕,然而獨立的元件通常不會處理。此外,如果您需要呼叫兩個不同的 API,開發人員 (也就是您) 會比較難執行「跳到這個標籤,然後前往這個畫面」等動作。最後,行動裝置的使用者介面有很多小小的設計細節,需要某些元件能察覺其他元件的配置或存在。例如,如果您有一個半透明的標籤列,則內容應該可以在其下方捲動,而且捲動檢視會在底部有一個內嵌項目,其高度等於標籤列的高度,這樣您就能看到所有內容。雙擊標籤列會讓目前活動的導覽堆疊跳到堆疊最上層,再點一次會讓該堆疊的目前活動捲動檢視捲動到最上層。儘管 React Navigation 目前還沒有內建所有這些行為,但將來會有的,如果您使用獨立的標籤檢視元件,這些功能您一個都用不到。

標籤導覽器包含一個堆疊,而且您要在特定畫面中隱藏標籤列

在此參考文件