版本:6.x
底部标签导航器
屏幕底部的简单标签栏,让您在不同的路由之间切换。路由是懒惰初始化的——它们的屏幕组件在首次聚焦之前不会被挂载。
安装
要使用此导航器,请确保您已安装 @react-navigation/native
及其依赖项(请遵循此指南),然后安装 @react-navigation/bottom-tabs
:
- npm
- 纱线
- 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
可选的导航器唯一 ID。这可以与navigation.getParent
一起使用,以在子导航器中引用此导航器。
初始路由名称
导航器首次加载时渲染的路由名称。
屏幕选项
导航器中屏幕的默认选项。
backBehavior
这控制在导航器中调用 goBack
时发生的事情。这包括在 Android 设备上按下返回按钮或使用返回手势。
它支持以下值:
firstRoute
- 返回到导航器中定义的第一个屏幕(默认)initialRoute
- 返回到传入的初始屏幕initialRouteName
属性,如果未传入,则默认为第一个屏幕order
- 返回到聚焦屏幕之前定义的屏幕历史
- 返回到导航器中最后访问的屏幕;如果同一屏幕被多次访问,较旧的条目将从历史记录中删除无
- 不处理返回按钮
分离非活动屏幕
用于指示是否应将非活动屏幕从视图层次结构中分离以节省内存的布尔值。这使得与 react-native-screens 的集成成为可能。默认为 true
。
场景容器样式
用于包装屏幕内容的组件的样式对象。
标签栏
返回一个 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>
尝试这个例子在 Snack
这个例子将渲染一个带标签的基本标签栏。
请注意,您不能在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');
}}
/>
);
}
选项
以下选项可用于配置导航器中的屏幕。这些可以在screenOptions
属性下的Tab.navigator
或options
属性下的Tab.Screen
中指定。
标题
通用标题,可用作headerTitle
和tabBarLabel
的后备。
标签栏标签
选项卡栏中显示的选项卡标题字符串或一个函数,该函数给定 { focused: boolean, color: string }
返回一个 React.Node,以在选项卡栏中显示。当未定义时,使用场景 title
。要隐藏,请参见 tabBarShowLabel
。
tabBarShowLabel
选项卡标签是否应该可见。默认为 true
。
标签栏标签位置
标签是显示在图标下方还是图标旁边。
below-icon
:标签显示在图标下方(典型于 iPhone)beside-icon
标签显示在图标旁边(iPad 上典型)
默认情况下,位置会根据设备宽度自动选择。
tabBarLabelStyle
选项卡标签的样式对象。
tabBarIcon
给定 { focused: boolean, color: string, size: number }
的函数返回一个 React.Node,以在标签栏中显示。
tabBarIconStyle
选项卡图标的样式对象。
tabBarBadge
在标签图标上显示的文本。接受一个 字符串
或一个 数字
。
tabBarBadgeStyle
选项卡图标上的徽章样式。您可以在此处指定背景颜色或文本颜色。
标签栏可访问性标签
选项卡按钮的可访问性标签。当用户点击选项卡时,屏幕阅读器会读取此标签。如果您没有选项卡的标签,建议设置此项。
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 Navigation 不会自动处理。
要获取底部标签栏的高度,您可以使用 BottomTabBarHeightContext
与 React 的 Context API 或 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()
为您的内容添加底部内边距。
懒惰
是否在首次访问时渲染此屏幕。默认为 true
。如果您希望在初始渲染时渲染屏幕,请将其设置为 false
。
失去焦点时卸载
当离开此屏幕时,是否应该卸载该屏幕。卸载屏幕会重置屏幕中的任何本地状态以及屏幕中嵌套导航器的状态。默认为 false
。
通常,我们不建议启用此属性,因为用户在切换标签时不希望丢失他们的导航历史。如果您启用此属性,请考虑这是否真的会为用户提供更好的体验。
失去焦点时冻结
布尔值,指示是否防止非活动屏幕重新渲染。默认为 false
。当在应用程序顶部运行 enableFreeze()
时,默认为 true
,该方法来自 react-native-screens
包。
需要 react-native-screens
版本 >=3.16.0。
仅支持 iOS 和 Android。
与标题相关的选项
您可以在这里找到与标题相关的选项列表。这些选项可以在screenOptions
属性下指定,属于Tab.navigator
或options
属性下的Tab.Screen
。您不必直接使用@react-navigation/elements
来使用这些选项,它们只是记录在该页面中。
除了这些,底部标签中还支持以下选项:
标题
自定义标题以替代默认标题。
这接受一个返回 React 元素的函数,用于显示为标题。该函数接收一个包含以下属性的对象作为参数:
导航
- 当前屏幕的导航对象。route
- 当前屏幕的路由对象。选项
- 当前屏幕的选项布局
- 屏幕的尺寸,包含高度
和宽度
属性。
示例:
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
来自 props。
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]);
尝试这个例子在 小吃 上
如果您有自定义标签栏,请确保发出此事件。
长按标签
此事件在用户长时间按下选项卡栏当前屏幕的选项卡按钮时触发。如果您有自定义选项卡栏,请确保发出此事件。
示例:
React.useEffect(() => {
const unsubscribe = navigation.addListener('tabLongPress', (e) => {
// Do something
});
return unsubscribe;
}, [navigation]);
帮助者
标签导航器向导航属性添加以下方法:
跳转到
导航到选项卡导航器中的现有屏幕。该方法接受以下参数:
name
- 字符串 - 跳转到的路由名称。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>
);
}