材质顶部标签导航器
一个位于屏幕顶部的材质设计主题标签栏,允许您通过点击标签或水平滑动在不同的路由之间切换。默认情况下,过渡是动画的。每个路由的屏幕组件会立即挂载。
这包装了 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>
此示例将渲染一个带有标签的基本选项卡栏。
请注意,您**不能**在tabBar
中使用useNavigation
钩子,因为useNavigation
仅在屏幕内可用。您将获得一个navigation
道具用于您的tabBar
,您可以使用它来代替
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
选项卡图标是否应可见。默认值为 false
。
tabBarBadge
一个函数,返回一个 React 元素,用作选项卡的徽章。
tabBarIndicator
一个函数,返回一个 React 元素作为选项卡栏指示器。
tabBarIndicatorStyle
选项卡栏指示器的样式对象。
tabBarIndicatorContainerStyle
包含选项卡栏指示器的视图的样式对象。
tabBarTestID
在测试中定位此选项卡按钮的 ID。
tabBarActiveTintColor
活动选项卡中图标和标签的颜色。
tabBarInactiveTintColor
非活动选项卡中图标和标签的颜色。
tabBarGap
选项卡栏中选项卡项目之间的间距。
示例
<Tab.Navigator
//...
screenOptions={{
tabBarGap: 10,
}}
></Tab.Navigator>
tabBarAndroidRipple
允许自定义 Android 水波纹效果。
示例
<Tab.Navigator
//...
screenOptions={{
tabBarAndroidRipple: { borderless: false },
}}
></Tab.Navigator>
tabBarPressColor
材质水波纹的颜色。
仅在 Android 上支持。
tabBarPressOpacity
按下选项卡的不透明度。
仅在 iOS 上支持。
tabBarBounces
布尔值,指示选项卡栏在过度滚动时是否会反弹。
tabBarScrollEnabled
布尔值,指示是否使选项卡栏可滚动。
如果将此设置为 true
,则还应在 tabBarItemStyle
中指定宽度,以提高初始渲染的性能。
tabBarIconStyle
选项卡图标容器的样式对象。
tabBarLabelStyle
选项卡标签的样式对象。
tabBarItemStyle
单个选项卡项目的样式对象。
tabBarContentContainerStyle
包含选项卡项目的视图的样式对象。
tabBarStyle
标签栏的样式对象。
swipeEnabled
布尔值,指示是否启用滑动手势。默认情况下启用滑动手势。传递 false
将禁用滑动手势,但用户仍然可以通过按下标签栏来切换标签。
lazy
此屏幕是否应延迟渲染。当设置为 true
时,屏幕将在进入视窗时渲染。默认情况下,所有屏幕都会渲染以提供更流畅的滑动体验。但您可能希望延迟渲染视窗外的屏幕,直到用户看到它们为止。要为该屏幕启用延迟渲染,请将 lazy
设置为 true
。
启用 lazy
后,延迟加载的屏幕通常需要一些时间才能在进入视窗时渲染。您可以使用 lazyPlaceholder
属性来自定义用户在此短时间内看到的内容。
lazyPreloadDistance
启用 lazy
后,您可以使用此属性指定应提前预加载多少个相邻屏幕。此值默认为 0
,这意味着延迟页面将在它们进入视窗时加载。
lazyPlaceholder
返回 React 元素的函数,如果此屏幕尚未渲染,则渲染该元素。lazy
选项也需要启用才能使其正常工作。
此视图通常只显示几秒钟。保持轻量级。
默认情况下,这将渲染 null
。
事件
导航器可以在某些操作时发出事件。支持的事件是
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
- string - 要跳转到的路由的名称。params
- object - 传递到目标路由的屏幕参数。
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>
);
}