跳至主要内容
版本:6.x

基于路由的不同状态栏配置

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

堆栈

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

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

function Screen1({ navigation }) {
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
title="Next screen"
onPress={() => navigation.navigate('Screen2')}
color="#fff"
/>
</View>
);
}

function Screen2({ navigation }) {
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
title="Next screen"
onPress={() => navigation.navigate('Screen1')}
/>
</View>
);
}

const Stack = createNativeStackNavigator();

export default function App() {
return (
<SafeAreaProvider>
<NavigationContainer>
<Stack.Navigator screenOptions={{ headerShown: false }}>
<Stack.Screen name="Screen1" component={Screen1} />
<Stack.Screen name="Screen2" component={Screen2} />
</Stack.Navigator>
</NavigationContainer>
</SafeAreaProvider>
);
}

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

标签和抽屉

如果您使用的是标签或抽屉导航器,它会稍微复杂一些,因为导航器中的所有屏幕都可能同时渲染并保持渲染 - 这意味着您设置的最后一个 StatusBar 配置将被使用(可能是在您的标签导航器的最后一个标签上,而不是用户正在看到的)。

为了解决这个问题,我们需要让状态栏组件感知屏幕焦点,并且仅在屏幕处于焦点时才渲染它。我们可以使用 useIsFocused hook 并创建一个包装组件来实现这一点。

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 组件。

function Screen1({ navigation }) {
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
title="Next screen"
onPress={() => navigation.navigate('Screen2')}
color="#fff"
/>
</View>
);
}

function Screen2({ navigation }) {
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
title="Next screen"
onPress={() => navigation.navigate('Screen1')}
/>
</View>
);
}

虽然不是必需的,但您也可以在原生堆栈导航器的屏幕中使用 FocusAwareStatusBar 组件。