原生堆栈导航器
原生堆栈导航器提供了一种方法,可以让您的应用程序在屏幕之间进行过渡,其中每个新屏幕都放置在堆栈的顶部。
此导航器使用原生 API UINavigationController
(在 iOS 上)和 Fragment
(在 Android 上),因此使用 createNativeStackNavigator
构建的导航将与使用这些 API 在原生上构建的应用程序具有完全相同的行为和性能特征。它还使用 react-native-web
提供基本的 Web 支持。
需要注意的是,虽然 @react-navigation/native-stack
提供了原生性能并公开了原生功能(例如 iOS 上的大标题等),但根据您的需求,它可能不如 @react-navigation/stack
可定制。因此,如果您需要比此导航器中提供的更多定制选项,请考虑使用 @react-navigation/stack
,它是一个更可定制的基于 JavaScript 的实现。
安装
要使用此导航器,请确保您已安装 @react-navigation/native
及其依赖项(请遵循本指南),然后安装 @react-navigation/native-stack
- npm
- Yarn
- pnpm
npm install @react-navigation/native-stack
yarn add @react-navigation/native-stack
pnpm add @react-navigation/native-stack
API 定义
💡 如果您在使用
createNativeStackNavigator
时遇到任何错误,请在react-native-screens
而不是react-navigation
存储库中打开问题!
要使用此导航器,请从 @react-navigation/native-stack
中导入它
import { createNativeStackNavigator } from '@react-navigation/native-stack';
const Stack = createNativeStackNavigator();
function MyStack() {
return (
<Stack.Navigator>
<Stack.Screen name="Home" component={Home} />
<Stack.Screen name="Notifications" component={Notifications} />
<Stack.Screen name="Profile" component={Profile} />
<Stack.Screen name="Settings" component={Settings} />
</Stack.Navigator>
);
}
属性
Stack.Navigator
组件接受以下属性
id
导航器的可选唯一 ID。这可以与 navigation.getParent
一起使用,以在子导航器中引用此导航器。
initialRouteName
在导航器首次加载时要渲染的路由的名称。
screenOptions
用于导航器中屏幕的默认选项。
选项
以下 选项 可用于配置导航器中的屏幕
title
可作为 headerTitle
备选的字符串。
headerBackButtonMenuEnabled
布尔值,指示是否在 iOS >= 14 后退按钮的长按时显示菜单。默认为 true
。
需要 react-native-screens
版本 >=3.3.0。
仅在 iOS 上受支持。
headerBackVisible
后退按钮在标题中是否可见。如果您已指定 headerLeft
,则可以使用它在 headerLeft
旁边显示后退按钮。
这不会影响堆栈中的第一个屏幕。
headerBackTitle
iOS 上后退按钮使用的标题字符串。默认为上一个场景的标题,或者如果空间不足则为“后退”。使用 headerBackTitleVisible: false
来隐藏它。
仅在 iOS 上受支持。
headerBackTitleVisible
后退按钮标题是否可见。
仅在 iOS 上受支持。
headerBackTitleStyle
标题后退标题的样式对象。支持的属性
fontFamily
fontSize
仅在 iOS 上受支持。
headerBackImageSource
在标题中显示为后退按钮图标的图像。默认情况下使用平台的后退图标图像
- iOS 上的 Chevron
- Android 上的箭头
headerLargeStyle
当显示大标题时标题的样式。如果 headerLargeTitle
为 true
并且任何可滚动内容的边缘到达标题的匹配边缘,则会显示大标题。
支持的属性
- backgroundColor
仅在 iOS 上受支持。
headerLargeTitle
是否启用带有大标题的标题,该标题在滚动时会折叠为常规标题。
为了使大标题在滚动时折叠,屏幕内容应包装在可滚动视图中,例如 ScrollView
或 FlatList
。如果可滚动区域没有填满屏幕,则大标题在滚动时不会折叠。您还需要在 ScrollView
、FlatList
等中指定 contentInsetAdjustmentBehavior="automatic"
。
仅在 iOS 上受支持。
headerLargeTitleShadowVisible
当显示大标题时,标题的阴影是否可见。
headerLargeTitleStyle
标题中大标题的样式对象。支持的属性
fontFamily
fontSize
fontWeight
color
仅在 iOS 上受支持。
headerShown
是否显示标题。默认情况下显示标题。将其设置为 false
会隐藏标题。
headerStyle
标题的样式对象。支持的属性
backgroundColor
headerShadowVisible
是否隐藏标题上的高程阴影(Android)或底部边框(iOS)。
headerTransparent
布尔值,指示导航栏是否为半透明。
默认值为 false
。将其设置为 true
会使标题绝对定位 - 这样标题就会浮动在屏幕上,覆盖下面的内容,并将背景颜色更改为 transparent
,除非在 headerStyle
中指定。
如果您想渲染半透明标题或模糊背景,这很有用。
请注意,如果您不希望内容出现在标题下方,则需要手动为内容添加顶部边距。React Navigation 不会自动执行此操作。
要获取标题的高度,您可以使用 HeaderHeightContext
与 React 的 Context API 或 useHeaderHeight
。
headerBlurEffect
半透明标题的模糊效果。headerTransparent
选项需要设置为 true
才能生效。
支持的值
extraLight
light
dark
regular
prominent
systemUltraThinMaterial
systemThinMaterial
systemMaterial
systemThickMaterial
systemChromeMaterial
systemUltraThinMaterialLight
systemThinMaterialLight
systemMaterialLight
systemThickMaterialLight
systemChromeMaterialLight
systemUltraThinMaterialDark
systemThinMaterialDark
systemMaterialDark
systemThickMaterialDark
systemChromeMaterialDark
仅在 iOS 上受支持。
headerBackground
返回一个 React 元素的函数,该元素将作为标题的背景渲染。这对于使用图像或渐变等背景很有用。
headerTintColor
标题的色调颜色。更改后退按钮和标题的颜色。
headerLeft
返回一个 React 元素,用于显示在标题左侧。这将替换后退按钮。请参阅 headerBackVisible
以显示后退按钮以及左侧元素。
headerRight
返回一个 React 元素,用于显示在标题右侧。
headerTitle
字符串或返回 React 元素的函数,用于标题。默认值为 title
或屏幕名称。
当传递函数时,它将在选项对象中接收 tintColor
和 children
作为参数。标题字符串在 children
中传递。
请注意,如果您通过传递函数来渲染自定义元素,则标题的动画将无法正常工作。
headerTitleAlign
如何对齐标题。可能的值
left
center
在 iOS 以外的平台上默认为 left
。
在 iOS 上不支持。它在 iOS 上始终为 center
,无法更改。
headerTitleStyle
标题的样式对象。支持的属性
fontFamily
fontSize
fontWeight
color
headerSearchBarOptions
在 iOS 上渲染原生搜索栏的选项。搜索栏很少是静态的,因此通常通过将对象传递给组件主体中的 headerSearchBarOptions
导航选项来控制它。您还需要在 ScrollView
、FlatList
等中指定 contentInsetAdjustmentBehavior="automatic"
。如果您没有 ScrollView
,请指定 headerTransparent: false
。
仅在 iOS 和 Android 上支持。
示例
React.useLayoutEffect(() => {
navigation.setOptions({
headerSearchBarOptions: {
// search bar options
},
});
}, [navigation]);
支持的属性如下所述。
autoCapitalize
控制用户输入时文本是否自动大写。可能的值
none
words
sentences
characters
默认值为 sentences
。
autoFocus
搜索栏显示时是否自动聚焦。默认值为 false
。
仅在 Android 上支持。
barTintColor
搜索栏背景颜色。默认情况下,栏色调颜色是半透明的。
仅在 iOS 上受支持。
tintColor
光标插入符号和取消按钮文本的颜色。
仅在 iOS 上受支持。
cancelButtonText
用于代替默认 Cancel
按钮文本的文本。
仅在 iOS 上受支持。
disableBackButtonOverride
后退按钮是否应该关闭搜索栏的文本输入。默认值为 false
。
仅在 Android 上支持。
hideNavigationBar
布尔值,指示在搜索期间是否隐藏导航栏。默认值为 true
。
仅在 iOS 上受支持。
hideWhenScrolling
布尔值,指示在滚动时是否隐藏搜索栏。默认值为 true
。
仅在 iOS 上受支持。
inputType
输入的类型。默认值为 "text"
。
支持的值
"text"
"phone"
"number"
"email"
仅在 Android 上支持。
obscureBackground
布尔值,指示是否使用半透明覆盖层遮挡底层内容。默认值为 true
。
placeholder
搜索栏为空时显示的文本。
textColor
搜索栏中文本的颜色。
hintTextColor
搜索栏中提示文本的颜色。
仅在 Android 上支持。
headerIconColor
标题中显示的搜索和关闭图标的颜色。
仅在 Android 上支持。
shouldShowHintSearchIcon
是否在搜索栏获得焦点时显示搜索提示图标。默认值为 true
。
仅在 Android 上支持。
onBlur
搜索栏失去焦点时调用的回调函数。
onCancelButtonPress
按下取消按钮时调用的回调函数。
onChangeText
文本发生变化时调用的回调函数。它接收搜索栏的当前文本值。
示例
const [search, setSearch] = React.useState('');
React.useLayoutEffect(() => {
navigation.setOptions({
headerSearchBarOptions: {
onChangeText: (event) => setSearch(event.nativeEvent.text),
},
});
}, [navigation]);
header
要使用的自定义标题,而不是默认标题。
这接受一个函数,该函数返回一个 React 元素作为标题显示。该函数接收一个包含以下属性的对象作为参数
navigation
- 当前屏幕的导航对象。route
- 当前屏幕的路由对象。options
- 当前屏幕的选项back
- 返回按钮的选项,包含一个带有title
属性的对象,用于返回按钮标签。
示例
import { getHeaderTitle } from '@react-navigation/elements';
// ..
header: ({ navigation, route, options, back }) => {
const title = getHeaderTitle(options, route.name);
return (
<MyHeader
title={title}
leftButton={
back ? <MyBackButton onPress={navigation.goBack} /> : undefined
}
style={options.headerStyle}
/>
);
};
要为导航器中的所有屏幕设置自定义标题,可以在导航器的 screenOptions
属性中指定此选项。
请注意,如果您指定了自定义标题,则本机功能(如大标题、搜索栏等)将无法使用。
statusBarAnimation
设置状态栏动画(类似于 StatusBar
组件)。在 iOS 上默认为 fade
,在 Android 上默认为 none
。
支持的值
"淡入淡出"
"无"
"滑动"
在 Android 上,设置 fade
或 slide
将设置状态栏颜色的过渡效果。在 iOS 上,此选项适用于状态栏的出现动画。
需要在您的 Info.plist
文件中设置 View controller-based status bar appearance -> YES
(或删除配置)。
仅在 Android 和 iOS 上支持。
statusBarHidden
是否应在此屏幕上隐藏状态栏。
需要在您的 Info.plist
文件中设置 View controller-based status bar appearance -> YES
(或删除配置)。
仅在 Android 和 iOS 上支持。
statusBarStyle
设置状态栏颜色(类似于 StatusBar
组件)。默认值为 auto
。
支持的值
"自动"
"反转"
(仅限 iOS)"深色"
"浅色"
需要在您的 Info.plist
文件中设置 View controller-based status bar appearance -> YES
(或删除配置)。
仅在 Android 和 iOS 上支持。
statusBarColor
设置状态栏颜色(类似于 StatusBar
组件)。默认值为初始状态栏颜色。
仅在 Android 上支持。
statusBarTranslucent
设置状态栏的半透明度(类似于 StatusBar
组件)。默认值为 false
。
仅在 Android 上支持。
contentStyle
场景内容的样式对象。
customAnimationOnGesture
是否应使用提供给 animation
属性的动画来执行关闭手势。默认值为 false
。
不影响以模态方式呈现的屏幕的行为。
仅在 iOS 上受支持。
fullScreenGestureEnabled
是否应在整个屏幕上使用关闭手势。使用此选项关闭手势会导致与 simple_push
相同的过渡动画。可以通过设置 customAnimationOnGesture
属性来更改此行为。由于平台限制,无法实现默认的 iOS 动画。默认值为 false
。
不影响以模态方式呈现的屏幕的行为。
仅在 iOS 上受支持。
gestureEnabled
是否可以使用手势关闭此屏幕。默认为 true
。仅在 iOS 上支持。
animationTypeForReplace
此屏幕替换另一个屏幕时使用的动画类型。默认为 pop
。
支持的值
push
: 新屏幕将执行推入动画。pop
: 新屏幕将执行弹出动画。
animation
屏幕在推入或弹出时应如何动画。
支持的值
default
: 使用平台默认动画fade
: 淡入或淡出屏幕fade_from_bottom
: 从底部淡入新屏幕flip
: 翻转屏幕,需要presentation: "modal"
(仅限 iOS)simple_push
: 默认动画,但没有阴影和原生标题过渡(仅限 iOS,在 Android 上使用默认动画)slide_from_bottom
: 从底部滑入新屏幕slide_from_right
: 从右侧滑入新屏幕(仅限 Android,在 iOS 上使用默认动画)slide_from_left
: 从左侧滑入新屏幕(仅限 Android,在 iOS 上使用默认动画)none
: 不要为屏幕设置动画
仅在 Android 和 iOS 上支持。
presentation
屏幕应如何呈现。
支持的值
card
: 新屏幕将被推入堆栈,这意味着默认动画将从 iOS 上的侧面滑动,Android 上的动画将根据操作系统版本和主题而有所不同。modal
: 新屏幕将以模态方式呈现。这也允许在屏幕内呈现嵌套堆栈。transparentModal
: 新屏幕将以模态方式呈现,但此外,前一个屏幕将保留,以便如果屏幕具有半透明背景,则仍然可以看到下面的内容。containedModal
: 将在 iOS 上使用“UIModalPresentationCurrentContext”模态样式,并在 Android 上回退到“modal”。containedTransparentModal
: 将在 iOS 上使用“UIModalPresentationOverCurrentContext”模态样式,并在 Android 上回退到“transparentModal”。fullScreenModal
: 将在 iOS 上使用“UIModalPresentationFullScreen”模态样式,并在 Android 上回退到“modal”。使用此呈现样式的屏幕无法通过手势关闭。formSheet
: 将在 iOS 上使用“UIModalPresentationFormSheet”模态样式,并在 Android 上回退到“modal”。
仅在 Android 和 iOS 上支持。
orientation
屏幕要使用的显示方向。
支持的值
default
- 在 iOS 上解析为“all”,但不包含“portrait_down”。在 Android 上,这允许系统决定最佳方向。all
: 允许所有方向。portrait
: 允许纵向方向。portrait_up
: 允许右侧纵向方向。portrait_down
: 允许倒置肖像方向。landscape
: 允许横向方向。landscape_left
: 允许左横向方向。landscape_right
: 允许右横向方向。
仅在 Android 和 iOS 上支持。
autoHideHomeIndicator
布尔值,指示是否应优先隐藏主屏幕指示器。默认值为 false
。
仅在 iOS 上受支持。
gestureDirection
设置滑动以关闭屏幕的方向。
支持的值
vertical
– 垂直关闭屏幕horizontal
– 水平关闭屏幕(默认)
当使用 vertical
选项时,选项 fullScreenGestureEnabled: true
、customAnimationOnGesture: true
和 animation: 'slide_from_bottom'
默认设置。
仅在 iOS 上受支持。
animationDuration
更改 iOS 上 slide_from_bottom
、fade_from_bottom
、fade
和 simple_push
过渡的持续时间(以毫秒为单位)。默认值为 350
。
default
和 flip
过渡的持续时间不可自定义。
仅在 iOS 上受支持。
navigationBarColor
设置导航栏颜色。默认值为初始状态栏颜色。
仅在 Android 上支持。
navigationBarHidden
布尔值,指示是否应隐藏导航栏。默认值为 false
。
仅在 Android 上支持。
freezeOnBlur
布尔值,指示是否阻止非活动屏幕重新渲染。默认值为 false
。当从 react-native-screens
包中运行 enableFreeze()
时,默认值为 true
。
需要 react-native-screens
版本 >=3.16.0。
仅在 iOS 和 Android 上支持。
事件
导航器可以在某些操作时发出事件。支持的事件是
transitionStart
当当前屏幕的过渡动画开始时,会触发此事件。
事件数据
e.data.closing
- 布尔值,指示屏幕正在打开还是关闭。
示例
React.useEffect(() => {
const unsubscribe = navigation.addListener('transitionStart', (e) => {
// Do something
});
return unsubscribe;
}, [navigation]);
transitionEnd
当当前屏幕的过渡动画结束时,会触发此事件。
事件数据
e.data.closing
- 布尔值,指示屏幕是打开还是关闭。
示例
React.useEffect(() => {
const unsubscribe = navigation.addListener('transitionEnd', (e) => {
// Do something
});
return unsubscribe;
}, [navigation]);
助手
原生堆栈导航器向导航属性添加了以下方法
replace
用堆栈中的新屏幕替换当前屏幕。该方法接受以下参数
name
- string - 要推送到堆栈的路由名称。params
- object - 传递给目标路由的屏幕参数。
navigation.replace('Profile', { owner: 'Michaś' });
push
将新屏幕推送到堆栈顶部并导航到它。该方法接受以下参数
name
- string - 要推送到堆栈的路由名称。params
- object - 传递给目标路由的屏幕参数。
navigation.push('Profile', { owner: 'Michaś' });
pop
从堆栈中弹出当前屏幕并导航回上一个屏幕。它接受一个可选参数 (count
),允许您指定要弹出的屏幕数量。
navigation.pop();
popToTop
弹出堆栈中除第一个屏幕之外的所有屏幕并导航到它。
navigation.popToTop();
示例
import { createNativeStackNavigator } from '@react-navigation/native-stack';
const Stack = createNativeStackNavigator();
function MyStack() {
return (
<Stack.Navigator
initialRouteName="Home"
screenOptions={{
headerTintColor: 'white',
headerStyle: { backgroundColor: 'tomato' },
}}
>
<Stack.Screen
name="Home"
component={Home}
options={{
title: 'Awesome app',
}}
/>
<Stack.Screen
name="Profile"
component={Profile}
options={{
title: 'My profile',
}}
/>
<Stack.Screen
name="Settings"
component={Settings}
options={{
gestureEnabled: false,
}}
/>
</Stack.Navigator>
);
}