Skip to main content
Version: 6.x

底部选项卡导航器

屏幕底部有一个简单的选项卡栏,可让你在不同的路由之间切换。路由是延迟初始化的 - 它们的屏幕组件在第一次聚焦之前不会安装。

¥A simple tab bar on the bottom of the screen that lets you switch between different routes. Routes are lazily initialized -- their screen components are not mounted until they are first focused.

安装

¥Installation

要使用此导航器,请确保你有 @react-navigation/native 及其依赖(遵循本指南),然后安装 @react-navigation/bottom-tabs

¥To use this navigator, ensure that you have @react-navigation/native and its dependencies (follow this guide), then install @react-navigation/bottom-tabs:

npm install @react-navigation/bottom-tabs

API 定义

¥API Definition

要使用此选项卡导航器,请从 @react-navigation/bottom-tabs 导入它:

¥To use this tab navigator, import it from @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>
);
}
注意

完整的使用指南请访问 选项卡导航

¥For a complete usage guide please visit Tab Navigation

属性

¥Props

Tab.Navigator 组件接受以下属性:

¥The Tab.Navigator component accepts following props:

id

导航器的可选唯一 ID。这可以与 navigation.getParent 一起使用来在子导航器中引用该导航器。

¥Optional unique ID for the navigator. This can be used with navigation.getParent to refer to this navigator in a child navigator.

initialRouteName

首次加载导航器时要呈现的路由的名称。

¥The name of the route to render on first load of the navigator.

screenOptions

用于导航器屏幕的默认选项。

¥Default options to use for the screens in the navigator.

backBehavior

这控制在导航器中调用 goBack 时发生的情况。这包括在 Android 上按设备的后退按钮或后退手势。

¥This controls what happens when goBack is called in the navigator. This includes pressing the device's back button or back gesture on Android.

它支持以下值:

¥It supports the following values:

  • firstRoute - 返回导航器中定义的第一个屏幕(默认)

    ¥firstRoute - return to the first screen defined in the navigator (default)

  • initialRoute - 返回 initialRouteName prop 中传入的初始屏幕,如果不传则默认到第一屏幕

    ¥initialRoute - return to initial screen passed in initialRouteName prop, if not passed, defaults to the first screen

  • order - 返回到聚焦屏幕之前定义的屏幕

    ¥order - return to screen defined before the focused screen

  • history - 返回导航器中上次访问的屏幕;如果多次访问同一屏幕,较旧的条目将从历史记录中删除

    ¥history - return to last visited screen in the navigator; if the same screen is visited multiple times, the older entries are dropped from the history

  • none - 不处理后退按钮

    ¥none - do not handle back button

detachInactiveScreens

布尔值用于指示是否应从视图层次结构中分离非活动屏幕以节省内存。这使得能够与 react-native-screens 集成。默认为 true

¥Boolean used to indicate whether inactive screens should be detached from the view hierarchy to save memory. This enables integration with react-native-screens. Defaults to true.

sceneContainerStyle

封装屏幕内容的组件的样式对象。

¥Style object for the component wrapping the screen content.

tabBar

返回一个 React 元素以显示为选项卡栏的函数。 =

¥Function that returns a React element to display as the tab bar.

示例:

¥Example:

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>

此示例将呈现带有标签的基本选项卡栏。

¥This example will render a basic tab bar with labels.

请注意,你不能在 tabBar 内部使用 useNavigation 钩子,因为 useNavigation 只能在屏幕内部使用。你将获得 tabBarnavigation 属性,你可以使用它来代替:

¥Note that you cannot use the useNavigation hook inside the tabBar since useNavigation is only available inside screens. You get a navigation prop for your tabBar which you can use instead:

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

选项

¥Options

以下 options 可用于配置导航器中的屏幕。这些可以在 Tab.navigatorscreenOptions 属性或 Tab.Screenoptions 属性下指定。

¥The following options can be used to configure the screens in the navigator. These can be specified under screenOptions prop of Tab.navigator or options prop of Tab.Screen.

title

可用作 headerTitletabBarLabel 后备的通用标题。

¥Generic title that can be used as a fallback for headerTitle and tabBarLabel.

tabBarLabel

显示在选项卡栏中的选项卡的标题字符串或给定 { focused: boolean, color: string } 返回 React.Node 的函数,以显示在选项卡栏中。未定义时,使用场景 title。要隐藏,请参阅 tabBarShowLabel

¥Title string of a tab displayed in the tab bar or a function that given { focused: boolean, color: string } returns a React.Node, to display in tab bar. When undefined, scene title is used. To hide, see tabBarShowLabel.

tabBarShowLabel

选项卡标签是否可见。默认为 true

¥Whether the tab label should be visible. Defaults to true.

tabBarLabelPosition

标签是显示在图标下方还是图标旁边。

¥Whether the label is shown below the icon or beside the icon.

  • below-icon:标签显示在图标下方(iPhone 的典型情况)

    ¥below-icon: the label is shown below the icon (typical for iPhones)

  • beside-icon 标签显示在图标旁边(iPad 的典型情况)

    ¥beside-icon the label is shown next to the icon (typical for iPad)

默认情况下,位置是根据设备宽度自动选择的。

¥By default, the position is chosen automatically based on device width.

tabBarLabelStyle

选项卡标签的样式对象。

¥Style object for the tab label.

tabBarIcon

给定 { focused: boolean, color: string, size: number } 的函数返回一个 React.Node,以显示在选项卡栏中。

¥Function that given { focused: boolean, color: string, size: number } returns a React.Node, to display in the tab bar.

tabBarIconStyle

选项卡图标的样式对象。

¥Style object for the tab icon.

tabBarBadge

要在选项卡图标上的徽章中显示的文本。接受 stringnumber

¥Text to show in a badge on the tab icon. Accepts a string or a number.

tabBarBadgeStyle

选项卡图标上的徽章样式。你可以在此处指定背景颜色或文本颜色。

¥Style for the badge on the tab icon. You can specify a background color or text color here.

tabBarAccessibilityLabel

选项卡按钮的辅助功能标签。当用户点击选项卡时,屏幕阅读器会读取此内容。如果你没有选项卡标签,建议设置此项。

¥Accessibility label for the tab button. This is read by the screen reader when the user taps the tab. It's recommended to set this if you don't have a label for the tab.

tabBarTestID

在测试中找到此选项卡按钮的 ID。

¥ID to locate this tab button in tests.

tabBarButton

返回一个 React 元素以呈现为选项卡栏按钮的函数。它封装着图标和标签。默认渲染 Pressable

¥Function which returns a React element to render as the tab bar button. It wraps the icon and label. Renders Pressable by default.

你可以在此处指定自定义实现:

¥You can specify a custom implementation here:

tabBarButton: (props) => <TouchableOpacity {...props} />;

tabBarActiveTintColor

活动选项卡中图标和标签的颜色。

¥Color for the icon and label in the active tab.

tabBarInactiveTintColor

非活动选项卡中图标和标签的颜色。

¥Color for the icon and label in the inactive tabs.

tabBarActiveBackgroundColor

活动选项卡的背景颜色。

¥Background color for the active tab.

tabBarInactiveBackgroundColor

非活动选项卡的背景颜色。

¥Background color for the inactive tabs.

tabBarHideOnKeyboard

键盘打开时标签栏是否隐藏。默认为 false

¥Whether the tab bar is hidden when the keyboard opens. Defaults to false.

tabBarItemStyle

选项卡项容器的样式对象。

¥Style object for the tab item container.

tabBarStyle

选项卡栏的样式对象。你可以在此处配置背景颜色等样式。

¥Style object for the tab bar. You can configure styles such as background color here.

要在选项卡栏下显示屏幕,可以将 position 样式设置为绝对:

¥To show your screen under the tab bar, you can set the position style to absolute:

<Tab.Navigator
screenOptions={{
tabBarStyle: { position: 'absolute' },
}}
>

如果你有绝对定位的标签栏,你可能还需要为内容添加底部边距。React Navigation 不会自动执行此操作。

¥You also might need to add a bottom margin to your content if you have a absolutely positioned tab bar. React Navigation won't do it automatically.

要获取底部选项卡栏的高度,可以将 BottomTabBarHeightContextReact 的上下文 APIuseBottomTabBarHeight 结合使用:

¥To get the height of the bottom tab bar, you can use BottomTabBarHeightContext with React's Context API or useBottomTabBarHeight:

import { BottomTabBarHeightContext } from '@react-navigation/bottom-tabs';

// ...

<BottomTabBarHeightContext.Consumer>
{tabBarHeight => (
/* render something */
)}
</BottomTabBarHeightContext.Consumer>

or

import { useBottomTabBarHeight } from '@react-navigation/bottom-tabs';

// ...

const tabBarHeight = useBottomTabBarHeight();

tabBarBackground

返回一个 React 元素用作选项卡栏背景的函数。你可以渲染图片、渐变、模糊视图等:

¥Function which returns a React Element to use as background for the tab bar. You could render an image, a gradient, blur view etc.:

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() 为你的内容添加底部填充。

¥When using BlurView, make sure to set position: 'absolute' in tabBarStyle as well. You'd also need to use useBottomTabBarHeight() to add a bottom padding to your content.

lazy

该屏幕是否应在第一次访问时呈现。默认为 true。如果你想在初始渲染时渲染屏幕,请将其设置为 false

¥Whether this screens should render the first time it's accessed. Defaults to true. Set it to false if you want to render the screen on initial render.

unmountOnBlur

当离开该屏幕时是否应卸载该屏幕。卸载屏幕会重置屏幕中的任何本地状态以及屏幕中嵌套导航器的状态。默认为 false

¥Whether this screen should be unmounted when navigating away from it. Unmounting a screen resets any local state in the screen as well as state of nested navigators in the screen. Defaults to false.

通常,我们不建议启用此属性,因为用户不希望在切换选项卡时丢失其导航历史记录。如果启用此属性,请考虑这是否真的能为用户提供更好的体验。

¥Normally, we don't recommend enabling this prop as users don't expect their navigation history to be lost when switching tabs. If you enable this prop, please consider if this will actually provide a better experience for the user.

freezeOnBlur

布尔值,指示是否阻止非活动屏幕重新渲染。默认为 false。当 react-native-screens 包中的 enableFreeze() 在应用顶部运行时,默认为 true

¥Boolean indicating whether to prevent inactive screens from re-rendering. Defaults to false. Defaults to true when enableFreeze() from react-native-screens package is run at the top of the application.

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

¥Requires react-native-screens version >=3.16.0.

仅支持 iOS 和 Android。

¥Only supported on iOS and Android.

¥Header related options

你可以找到标题相关选项 此处 的列表。这些 options 可以在 Tab.navigatorscreenOptions 属性或 Tab.Screenoptions 属性下指定。你不必直接使用 @react-navigation/elements 来使用这些选项,它们只是记录在该页面中。

¥You can find the list of header related options here. These options can be specified under screenOptions prop of Tab.navigator or options prop of Tab.Screen. You don't have to be using @react-navigation/elements directly to use these options, they are just documented in that page.

除此之外,底部选项卡还支持以下选项:

¥In addition to those, the following options are also supported in bottom tabs:

使用自定义标头代替默认标头。

¥Custom header to use instead of the default header.

它接受一个返回 React 元素以显示为标题的函数。该函数接收一个包含以下属性的对象作为参数:

¥This accepts a function that returns a React Element to display as a header. The function receives an object containing the following properties as the argument:

  • navigation - 当前屏幕的导航对象。

    ¥navigation - The navigation object for the current screen.

  • route - 当前屏幕的路由对象。

    ¥route - The route object for the current screen.

  • options - 当前屏幕的选项

    ¥options - The options for the current screen

  • layout - 屏幕尺寸,包含 heightwidth 属性。

    ¥layout - Dimensions of the screen, contains height and width properties.

示例:

¥Example:

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

// ..

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

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

要为导航器中的所有屏幕设置自定义标题,你可以在导航器的 screenOptions 属性中指定此选项。

¥To set a custom header for all the screens in the navigator, you can specify this option in the screenOptions prop of the navigator.

headerStyle 中指定 height

¥Specify a height in headerStyle

如果你的自定义标题高度与默认标题高度不同,那么你可能会注意到由于测量异步而导致的故障。明确指定高度将避免此类故障。

¥If your custom header's height differs from the default header height, then you might notice glitches due to measurement being async. Explicitly specifying the height will avoid such glitches.

示例:

¥Example:

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

请注意,默认情况下,此样式不会应用于标头,因为你可以控制自定义标头的样式。如果你也想将此样式应用于标题,请使用 props 中的 options.headerStyle

¥Note that this style is not applied to the header by default since you control the styling of your custom header. If you also want to apply this style to your header, use options.headerStyle from the props.

headerShown

是否显示或隐藏屏幕标题。默认情况下显示标题。将其设置为 false 会隐藏标题。

¥Whether to show or hide the header for the screen. The header is shown by default. Setting this to false hides the header.

活动

¥Events

导航器可以对某些操作进行 触发事件。支持的事件有:

¥The navigator can emit events on certain actions. Supported events are:

tabPress

当用户按下选项卡栏中当前屏幕的选项卡按钮时会触发此事件。默认情况下,按 Tab 键会执行以下几项操作:

¥This event is fired when the user presses the tab button for the current screen in the tab bar. By default a tab press does several things:

  • 如果选项卡未获得焦点,按下选项卡将使该选项卡获得焦点

    ¥If the tab is not focused, tab press will focus that tab

  • 如果该选项卡已获得焦点:

    ¥If the tab is already focused:

    • 如果选项卡的屏幕呈现滚动视图,你可以使用 useScrollToTop 将其滚动到顶部

      ¥If the screen for the tab renders a scroll view, you can use useScrollToTop to scroll it to top

    • 如果选项卡的屏幕呈现堆栈导航器,则会在堆栈上执行 popToTop 操作

      ¥If the screen for the tab renders a stack navigator, a popToTop action is performed on the stack

要防止默认行为,你可以调用 event.preventDefault

¥To prevent the default behavior, you can call event.preventDefault:

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

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

return unsubscribe;
}, [navigation]);

如果你有自定义选项卡栏,请确保发出此事件。

¥If you have a custom tab bar, make sure to emit this event.

tabLongPress

当用户长时间按下选项卡栏中当前屏幕的选项卡按钮时会触发此事件。如果你有自定义选项卡栏,请确保发出此事件。

¥This event is fired when the user presses the tab button for the current screen in the tab bar for an extended period. If you have a custom tab bar, make sure to emit this event.

示例:

¥Example:

React.useEffect(() => {
const unsubscribe = navigation.addListener('tabLongPress', (e) => {
// Do something
});

return unsubscribe;
}, [navigation]);

帮手

¥Helpers

选项卡导航器将以下方法添加到导航属性中:

¥The tab navigator adds the following methods to the navigation prop:

jumpTo

导航到选项卡导航器中的现有屏幕。该方法接受以下参数:

¥Navigates to an existing screen in the tab navigator. The method accepts following arguments:

  • name - string - 要跳转到的路由名称。

    ¥name - string - Name of the route to jump to.

  • params - object - 用于目标路由的屏幕参数。

    ¥params - object - Screen params to use for the destination route.

navigation.jumpTo('Profile', { owner: 'Michaś' });

示例

¥Example

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>
);
}