This documentation is available as Markdown for AI agents and LLMs. See the full Markdown index or append .md to any documentation URL.

原生选项卡

编辑页面

了解如何在 Expo Router 中使用原生选项卡布局。


使用 Expo Router 的 Liquid Glass 选项卡
使用 Expo Router 的 Liquid Glass 选项卡

了解如何使用原生选项卡在 iOS 上通过 Expo Router 创建液态玻璃选项卡。

选项卡是应用中不同部分之间导航的常见方式。在 Expo Router 中,你可以根据需要使用不同的选项卡布局。本指南介绍原生选项卡。与 其他选项卡布局 不同,原生选项卡使用原生系统选项卡栏。

其他选项卡布局请参见:

自定义选项卡

如果你的应用需要完全自定义的设计,而系统选项卡无法实现,请查看自定义选项卡。

JavaScript 选项卡

如果你已经在使用 React Navigation 的选项卡,请查看 JavaScript 选项卡。

或者,你也可以向 sfxcassetdrawablemdsrc 属性传入 {default: ..., selected: ...},为默认状态和选中状态指定不同的图标。

矢量图标

你可以通过向 src 属性传入图片源,来渲染图标字体中的图标,例如 react-native-vector-icons 提供的图标。每个图标集都会提供 getImageSourceSync 方法,该方法可以将字形栅格化为图片源,然后直接传给 src

这在 Android 上很有用,因为内置的 md 属性只能渲染轮廓样式的 Material Symbols。Material Design Icons 这样的图标字体同时提供轮廓和实心字形(例如 home-outlinehome),因此你可以显示不同的默认图标和选中图标。

首先,安装你想使用的图标集,以及 @react-native-vector-icons/get-image。后者提供了 getImageSourceSync 所依赖的原生模块。下面的示例使用 @react-native-vector-icons/material-design-icons 图标集:

getImageSourceSync 是同步方法,因此应在模块作用域中计算一次图片源,而不是在每次渲染时计算。将 srcsf 结合使用,可以在 Android 上使用矢量图标,在 iOS 上使用 SF Symbols。在 iOS 上,sf 的优先级高于 src;在 Android 上,如果没有可用的图标,则会回退到 src

src/app/_layout.tsx
import MaterialDesignIcons from '@react-native-vector-icons/material-design-icons'; import { NativeTabs } from 'expo-router/unstable-native-tabs'; const homeIcon = MaterialDesignIcons.getImageSourceSync('home', 24, 'black'); const starOutlineIcon = MaterialDesignIcons.getImageSourceSync('star-outline', 24, 'black'); const starIcon = MaterialDesignIcons.getImageSourceSync('star', 24, 'black'); export default function TabLayout() { return ( <NativeTabs> <NativeTabs.Trigger name="index"> {/* `sf` 在 iOS 上使用,`src`(矢量图标)在 Android 上使用。 */} <NativeTabs.Trigger.Icon sf="house" src={homeIcon} /> </NativeTabs.Trigger> <NativeTabs.Trigger name="explore"> {/* 未选中时显示轮廓样式,选中时显示实心样式。 */} <NativeTabs.Trigger.Icon sf={{ default: 'star', selected: 'star.fill' }} src={{ default: starOutlineIcon, selected: starIcon }} /> </NativeTabs.Trigger> </NativeTabs> ); }

禁用的选项卡

你可以通过在 NativeTabs.Trigger 组件上设置 disabled 属性来阻止原生选择某个选项卡。为 true 时,点击选项卡栏中的该选项卡不会改变当前聚焦的选项卡。该选项卡仍然可见——如果你想将其从选项卡栏中完全移除,请使用 hidden

src/app/_layout.tsx
import { NativeTabs } from 'expo-router/unstable-native-tabs'; export default function TabLayout() { return ( <NativeTabs> <NativeTabs.Trigger name="index"> <NativeTabs.Trigger.Label>主页</NativeTabs.Trigger.Label> </NativeTabs.Trigger> <NativeTabs.Trigger name="settings" disabled> <NativeTabs.Trigger.Label>设置</NativeTabs.Trigger.Label> </NativeTabs.Trigger> </NativeTabs> ); }

Android 上的键盘规避

默认情况下,在 Android 上,键盘会覆盖原生选项卡栏。若要让选项卡栏上移到键盘上方,请在 NativeTabs 上传入 tabBarRespectsIMEInsets 属性:

app/_layout.tsx
import { NativeTabs } from 'expo-router/unstable-native-tabs'; export default function TabLayout() { return ( <NativeTabs tabBarRespectsIMEInsets> <NativeTabs.Trigger name="index" /> <NativeTabs.Trigger name="profile" /> </NativeTabs> ); }

By default on Android, the keyboard overlays the native tab bar. To have the tab bar lift above the keyboard instead, pass the tabBarRespectsIMEInsets prop on NativeTabs:

app/_layout.tsx
import { NativeTabs } from 'expo-router/unstable-native-tabs'; export default function TabLayout() { return ( <NativeTabs tabBarRespectsIMEInsets> <NativeTabs.Trigger name="index" /> <NativeTabs.Trigger name="profile" /> </NativeTabs> ); }

支持浅色和深色模式的应用:

仅支持深色模式的应用:

src/app/_layout.tsx
import { ThemeProvider, DarkTheme } from 'expo-router'; import { NativeTabs } from 'expo-router/unstable-native-tabs'; export default function TabLayout() { return ( <ThemeProvider value={DarkTheme}> <NativeTabs>{/* 选项卡 */}</NativeTabs> </ThemeProvider> ); }

支持浅色和深色模式的应用:

仅支持深色模式的应用:

app/_layout.tsx
import { ThemeProvider, DarkTheme } from 'expo-router'; import { NativeTabs } from 'expo-router/unstable-native-tabs'; export default function TabLayout() { return ( <ThemeProvider value={DarkTheme}> <NativeTabs>{/* 选项卡 */}</NativeTabs> </ThemeProvider> ); }
Android 上最多只能有 5 个选项卡

在 Android 上,选项卡栏最多只能有 5 个选项卡。此限制来自平台的 Material Tabs 组件。