Skip to main content
Version: 7.x

材质顶部选项卡导航器

屏幕顶部的材料设计主题选项卡栏,可让你通过点击选项卡或水平滑动来在不同路由之间切换。默认情况下,过渡是动画的。每条路由的屏幕组件都会立即安装。

¥A material-design themed tab bar on the top of the screen that lets you switch between different routes by tapping the tabs or swiping horizontally. Transitions are animated by default. Screen components for each route are mounted immediately.

这封装了 react-native-tab-view。如果你想在不集成 React Navigation 的情况下使用选项卡视图,请直接使用该库。

¥This wraps react-native-tab-view. If you want to use the tab view without React Navigation integration, use the library directly instead.

安装

¥Installation

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

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

npm install @react-navigation/material-top-tabs

然后,你需要安装导航器所需的 react-native-pager-view

¥Then, you need to install react-native-pager-view which is required by the navigator.

如果你有 Expo 托管项目,请在项目目录中运行:

¥If you have a Expo managed project, in your project directory, run:

npx expo install react-native-pager-view

如果你有一个裸露的 React Native 项目,请在项目目录中运行:

¥If you have a bare React Native project, in your project directory, run:

npm install react-native-pager-view

如果你使用的是 Mac 并针对 iOS 进行开发,则还需要安装 pod(通过 可可足类)来完成链接。

¥If you're on a Mac and developing for iOS, you also need to install the pods (via Cocoapods) to complete the linking.

npx pod-install ios

用法

¥Usage

要使用此导航器,请从 @react-navigation/material-top-tabs 导入它:

¥To use this navigator, import it from @react-navigation/material-top-tabs:

import { createMaterialTopTabNavigator } from '@react-navigation/material-top-tabs';

const MyTabs = createMaterialTopTabNavigator({
screens: {
Home: HomeScreen,
Profile: ProfileScreen,
},
});
Try on Snack

API 定义

¥API Definition

属性

¥Props

除了所有导航器共享的 常用属性 之外,Material 顶部标签导航器组件还接受以下附加属性:

¥In addition to the common props shared by all navigators, the material top tabs navigator component accepts the following additional props:

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

tabBarPosition

选项卡视图中选项卡栏的位置。可能的值为 'top''bottom'。默认为 'top'

¥Position of the tab bar in the tab view. Possible values are 'top' and 'bottom'. Defaults to 'top'.

keyboardDismissMode

指示键盘是否因拖动手势而消失的字符串。可能的值为:

¥String indicating whether the keyboard gets dismissed in response to a drag gesture. Possible values are:

  • 'auto'(默认):当索引更改时,键盘将消失。

    ¥'auto' (default): the keyboard is dismissed when the index changes.

  • 'on-drag':当拖动开始时键盘将消失。

    ¥'on-drag': the keyboard is dismissed when a drag begins.

  • 'none':拖动不会关闭键盘。

    ¥'none': drags do not dismiss the keyboard.

initialLayout

包含屏幕初始高度和宽度的对象。通过这个将提高初始渲染性能。对于大多数应用来说,这是一个很好的默认值:

¥Object containing the initial height and width of the screens. Passing this will improve the initial rendering performance. For most apps, this is a good default:

{
width: Dimensions.get('window').width;
}

sceneContainerStyle

应用于环绕每个屏幕的视图的样式。你可以传递它来覆盖一些默认样式,例如溢出裁剪。

¥Style to apply to the view wrapping each screen. You can pass this to override some default styles such as overflow clipping.

style

应用于选项卡视图容器的样式。

¥Style to apply to the tab view container.

tabBar

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

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

示例:

¥Example:

import { Animated, View, TouchableOpacity, Platform } from 'react-native';
import { useLinkBuilder, useTheme } from '@react-navigation/native';

function MyTabBar({ state, descriptors, navigation, position }) {
const { colors } = useTheme();
const { buildHref } = useLinkBuilder();

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
href={buildHref(route.name, route.params)}
accessibilityRole={Platform.OS === 'web' ? 'link' : 'button'}
accessibilityState={isFocused ? { selected: true } : {}}
accessibilityLabel={options.tabBarAccessibilityLabel}
testID={options.tabBarButtonTestID}
onPress={onPress}
onLongPress={onLongPress}
style={{ flex: 1 }}
>
<Animated.Text style={{ opacity, color: colors.text }}>
{label}
</Animated.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
onPress={() => {
// Navigate using the `navigation` prop that you received
navigation.navigate('SomeScreen');
}}
>
Go somewhere
</Button>
);
}

选项

¥Options

以下 options 可用于配置导航器中的屏幕:

¥The following options can be used to configure the screens in the navigator:

示例:

¥Example:

<Tab.Navigator
screenOptions={{
tabBarLabelStyle: { fontSize: 12 },
tabBarItemStyle: { width: 100 },
tabBarStyle: { backgroundColor: 'powderblue' },
}}
>
{/* ... */}
</Tab.Navigator>

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 option.

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.

tabBarAllowFontScaling

标签字体是否应缩放以尊重文本大小辅助功能设置。

¥Whether label font should scale to respect Text Size accessibility settings.

tabBarShowLabel

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

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

tabBarIcon

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

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

tabBarShowIcon

选项卡图标是否可见。默认为 false

¥Whether the tab icon should be visible. Defaults to false.

tabBarBadge

返回一个 React 元素用作选项卡徽章的函数。

¥Function that returns a React element to use as a badge for the tab.

tabBarIndicator

返回 React 元素作为选项卡栏指示器的函数。

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

tabBarIndicatorStyle

选项卡栏指示器的样式对象。

¥Style object for the tab bar indicator.

tabBarIndicatorContainerStyle

包含选项卡栏指示器的视图的样式对象。

¥Style object for the view containing the tab bar indicator.

tabBarButtonTestID

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

¥ID to locate this tab button in tests.

tabBarActiveTintColor

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

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

tabBarInactiveTintColor

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

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

tabBarPressColor

材质波纹的颜色(仅限 Android >= 5.0)。

¥Color for material ripple (Android >= 5.0 only).

tabBarPressOpacity

按下的选项卡的不透明度(仅限 iOS 和 Android < 5.0)。

¥Opacity for pressed tab (iOS and Android < 5.0 only).

tabBarBounces

布尔值,指示标签栏在过度滚动时是否弹起。

¥Boolean indicating whether the tab bar bounces when overscrolling.

tabBarScrollEnabled

布尔值,指示是否使选项卡栏可滚动。

¥Boolean indicating whether to make the tab bar scrollable.

如果将其设置为 true,则还应该在 tabBarItemStyle 中指定宽度以提高初始渲染的性能。

¥If you set this to true, you should also specify a width in tabBarItemStyle to improve the performance of initial render.

tabBarIconStyle

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

¥Style object for the tab icon container.

tabBarLabelStyle

选项卡标签的样式对象。

¥Style object for the tab label.

tabBarItemStyle

各个选项卡项目的样式对象。

¥Style object for the individual tab items.

tabBarContentContainerStyle

包含选项卡项的视图的样式对象。

¥Style object for the view containing the tab items.

tabBarStyle

选项卡栏的样式对象。

¥Style object for the tab bar.

swipeEnabled

布尔值,指示是否启用滑动手势。默认情况下启用滑动手势。传递 false 将禁用滑动手势,但用户仍然可以通过按选项卡栏来切换选项卡。

¥Boolean indicating whether to enable swipe gestures. Swipe gestures are enabled by default. Passing false will disable swipe gestures, but the user can still switch tabs by pressing the tab bar.

lazy

该屏幕是否应该延迟渲染。当此项设置为 true 时,屏幕将在进入视口时进行渲染。默认情况下,所有屏幕都会渲染以提供更流畅的滑动体验。但是你可能希望推迟屏幕在视口之外的渲染,直到用户看到它们。要为此屏幕启用延迟渲染,请将 lazy 设置为 true

¥Whether this screen should be lazily rendered. When this is set to true, the screen will be rendered as it comes into the viewport. By default all screens are rendered to provide a smoother swipe experience. But you might want to defer the rendering of screens out of the viewport until the user sees them. To enable lazy rendering for this screen, set lazy to true.

当你启用 lazy 时,延迟加载的屏幕在进入视口时通常需要一些时间来渲染。你可以使用 lazyPlaceholder 属性来自定义用户在这段短时间内看到的内容。

¥When you enable lazy, the lazy loaded screens will usually take some time to render when they come into the viewport. You can use the lazyPlaceholder prop to customize what the user sees during this short period.

lazyPreloadDistance

当启用 lazy 时,你可以使用此属性指定应提前预加载多少个相邻屏幕。该值默认为 0,这意味着惰性页面在进入视口时加载。

¥When lazy is enabled, you can specify how many adjacent screens should be preloaded in advance with this prop. This value defaults to 0 which means lazy pages are loaded as they come into the viewport.

lazyPlaceholder

如果此屏幕尚未渲染,则返回要渲染的 React 元素的函数。还需要启用 lazy 选项才能使其工作。

¥Function that returns a React element to render if this screen hasn't been rendered yet. The lazy option also needs to be enabled for this to work.

此视图通常仅显示一瞬间。保持轻便。

¥This view is usually only shown for a split second. Keep it lightweight.

默认情况下,这会渲染 null

¥By default, this renders null.

活动

¥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]);

tabLongPress

当用户长时间按下选项卡栏中当前屏幕的选项卡按钮时会触发此事件。

¥This event is fired when the user presses the tab button for the current screen in the tab bar for an extended period.

示例:

¥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 object:

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 pass to the destination route.

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

钩子

¥Hooks

Material 顶部标签导航器导出以下钩子:

¥The material top tab navigator exports the following hooks:

useTabAnimation

此钩子返回一个对象,其中包含一个动画值,该值表示选项卡的当前位置。这可用于根据选项卡的滑动位置为元素设置动画,例如选项卡指示器:

¥This hook returns an object containing an animated value that represents the current position of the tabs. This can be used to animate elements based on the swipe position of the tabs, such as the tab indicator:

import { Animated } from 'react-native';
import { useTabAnimation } from '@react-navigation/material-top-tabs';

function MyView() {
const { position } = useTabAnimation();

return (
<Animated.View
style={{
width: '50%',
height: 2,
backgroundColor: 'tomato',
transform: [{ translateX: position }],
}}
/>
);
}