安全区域

编辑

了解如何在 Expo 项目中为屏幕组件添加安全区域。


创建安全区域可以确保你的应用屏幕内容被正确地定位。这意味着内容不会被刘海、状态栏、主屏指示器以及其他设备物理硬件或操作系统控制的界面元素覆盖。当内容被覆盖时,会被这些界面元素遮挡。

以下是应用屏幕内容被 Android 状态栏遮挡的示例。在 iOS 上,相同的内容会被圆角、刘海和状态栏遮挡。

使用 react-native-safe-area-context

react-native-safe-area-context 提供了一个灵活的 API,用于处理 Android 和 iOS 设备的安全区域内边距。它还提供了一个 SafeAreaView 组件,你可以用它来替代 <View>,以便在屏幕组件中自动适配安全区域。

使用该库后,前面示例的结果会发生变化,因为内容会显示在安全区域内,如下所示:

安装

如果你是使用 默认模板 创建的项目,可以跳过 react-native-safe-area-context 的安装。该库作为 Expo Router 库的 peer 依赖被自动安装。否则,请运行以下命令进行安装:

Terminal
npx expo install react-native-safe-area-context

用法

你可以直接使用 SafeAreaView 来包裹你屏幕组件的内容。它是一个普通的 <View>,但会将安全区域的内边距作为额外的 padding 或 margin 应用。

app/index.tsx
import { Text } from 'react-native'; import { SafeAreaView } from 'react-native-safe-area-context'; export default function HomeScreen() { return ( <SafeAreaView style={{ flex: 1 }}> <Text>Content is in safe area.</Text> </SafeAreaView> ); }
使用了不同的Expo模板,但未安装Expo Router?

在你的屏幕组件中使用 SafeAreaView 之前,需在根组件文件(如 App.tsx)中导入并添加 SafeAreaProvider

App.tsx
import { SafeAreaProvider } from 'react-native-safe-area-context'; export default function App() { return ( return <SafeAreaProvider>...</SafeAreaProvider>; ); }

可选:useSafeAreaInsets 钩子

作为 SafeAreaView 的替代方案,你可以在屏幕组件中使用 useSafeAreaInsets hook。它可以直接访问安全区域的内边距(insets),让你能够根据该 hook 返回的内边距为 <View> 的每个边缘添加相应的 padding。

下面的示例使用了 useSafeAreaInsets hook。它通过 insets.top<View> 添加了顶部内边距。

app/index.tsx
import { Text, View } from 'react-native'; import { useSafeAreaInsets } from 'react-native-safe-area-context'; export default function HomeScreen() { const insets = useSafeAreaInsets(); return ( <View style={{ flex: 1, paddingTop: insets.top }}> <Text>Content is in safe area.</Text> </View> ); }

该 hook 提供的 insets 对象如下:

{ top: number, right: number, bottom: number, left: number }

附加信息

最小示例

下面是一个最小可用示例,演示如何使用 useSafeAreaInsets hook 为视图应用顶部内边距。

Using react-native-safe-area-context
import { Text, View } from 'react-native'; import { SafeAreaProvider, useSafeAreaInsets } from 'react-native-safe-area-context'; function HomeScreen() { const insets = useSafeAreaInsets(); return ( <View style={{ flex: 1, paddingTop: insets.top }}> <Text style={{ fontSize: 28 }}>Content is in safe area.</Text> </View> ); } export default function App() { return ( <SafeAreaProvider> <HomeScreen /> </SafeAreaProvider> ); }

与 React Navigation 一起使用

默认情况下,React Navigation 支持安全区域,并将 react-native-safe-area-context 作为并列依赖。更多信息请参见 React Navigation 文档

与 Web 一起使用

如果你的目标平台是 Web,请按照 使用部分 中的说明设置 SafeAreaProvider。如果你在进行服务端渲染(SSR),请参见该库文档中的 Web SSR 部分