Skip to main content
Version: 7.x

根据路由不同的状态栏配置

如果你没有导航标题,或者导航标题根据路由更改颜色,你需要确保内容使用正确的颜色。

¥If you don't have a navigation header, or your navigation header changes color based on the route, you'll want to ensure that the correct color is used for the content.

¥Stack

使用堆栈时这是一个简单的任务。你可以渲染由 React Native 公开的 StatusBar 组件,并设置你的配置。

¥This is a simple task when using a stack. You can render the StatusBar component, which is exposed by React Native, and set your config.

import * as React from 'react';
import { View, Text, StatusBar, StyleSheet } from 'react-native';
import {
createStaticNavigation,
useNavigation,
} from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import { Button } from '@react-navigation/elements';
import { useSafeAreaInsets } from 'react-native-safe-area-context';

function Screen1() {
const navigation = useNavigation();
const insets = useSafeAreaInsets();

return (
<View
style={[
styles.container,
{
backgroundColor: '#6a51ae',
paddingTop: insets.top,
paddingBottom: insets.bottom,
paddingLeft: insets.left,
paddingRight: insets.right,
},
]}
>
<StatusBar barStyle="light-content" backgroundColor="#6a51ae" />
<Text style={{ color: '#fff' }}>Light Screen</Text>
<Button onPress={() => navigation.navigate('Screen2')}>
Next screen
</Button>
</View>
);
}

function Screen2() {
const navigation = useNavigation();
const insets = useSafeAreaInsets();

return (
<View
style={[
styles.container,
{
backgroundColor: '#ecf0f1',
paddingTop: insets.top,
paddingBottom: insets.bottom,
paddingLeft: insets.left,
paddingRight: insets.right,
},
]}
>
<StatusBar barStyle="dark-content" backgroundColor="#ecf0f1" />
<Text>Dark Screen</Text>
<Button onPress={() => navigation.navigate('Screen1')}>
Next screen
</Button>
</View>
);
}

const RootStack = createNativeStackNavigator({
screenOptions: {
headerShown: false,
},
screens: {
Screen1: Screen1,
Screen2: Screen2,
},
});

const Navigation = createStaticNavigation(RootStack);

export default function App() {
return <Navigation />;
}

const styles = StyleSheet.create({
container: { flex: 1, justifyContent: 'center', alignItems: 'center' },
});
Try on Snack

标签和抽屉

¥Tabs and Drawer

如果你使用选项卡或抽屉式导航器,则情况会稍微复杂一些,因为导航器中的所有屏幕可能会同时渲染并保持渲染状态 - 这意味着将使用你设置的最后一个 StatusBar 配置(可能在选项卡导航器的最后一个选项卡上,而不是用户看到的)。

¥If you're using a tab or drawer navigator, it's a bit more complex because all of the screens in the navigator might be rendered at once and kept rendered - that means that the last StatusBar config you set will be used (likely on the final tab of your tab navigator, not what the user is seeing).

为了解决这个问题,我们必须让状态栏组件感知屏幕焦点,并仅在屏幕聚焦时才渲染它。我们可以通过使用 useIsFocused 并创建一个封装器组件来实现这一点:

¥To fix this, we'll have to do make the status bar component aware of screen focus and render it only when the screen is focused. We can achieve this by using the useIsFocused hook and creating a wrapper component:

import * as React from 'react';
import { StatusBar } from 'react-native';
import { useIsFocused } from '@react-navigation/native';

function FocusAwareStatusBar(props) {
const isFocused = useIsFocused();

return isFocused ? <StatusBar {...props} /> : null;
}

现在,我们的屏幕(Screen1.jsScreen2.js)将使用 FocusAwareStatusBar 组件,而不是 React Native 中的 StatusBar 组件:

¥Now, our screens (both Screen1.js and Screen2.js) will use the FocusAwareStatusBar component instead of the StatusBar component from React Native:

function Screen1() {
const navigation = useNavigation();
const insets = useSafeAreaInsets();

return (
<View
style={[
styles.container,
{
backgroundColor: '#6a51ae',
paddingTop: insets.top,
paddingBottom: insets.bottom,
paddingLeft: insets.left,
paddingRight: insets.right,
},
]}
>
<FocusAwareStatusBar barStyle="light-content" backgroundColor="#6a51ae" />
<Text style={{ color: '#fff' }}>Light Screen</Text>
<Button onPress={() => navigation.navigate('Screen2')}>
Next screen
</Button>
</View>
);
}

function Screen2() {
const navigation = useNavigation();
const insets = useSafeAreaInsets();

return (
<View
style={[
styles.container,
{
backgroundColor: '#ecf0f1',
paddingTop: insets.top,
paddingBottom: insets.bottom,
paddingLeft: insets.left,
paddingRight: insets.right,
},
]}
>
<FocusAwareStatusBar barStyle="dark-content" backgroundColor="#ecf0f1" />
<Text>Dark Screen</Text>
<Button onPress={() => navigation.navigate('Screen1')}>
Next screen
</Button>
</View>
);
}
Try on Snack

尽管不是必需的,你也可以在原生堆栈导航器的屏幕中使用 FocusAwareStatusBar 组件。

¥Although not necessary, you can use the FocusAwareStatusBar component in the screens of the native stack navigator as well.