基于路由的不同状态栏配置
如果你没有导航头部,或者你的导航头部颜色基于路由而变化,你将需要确保内容使用了正确的颜色。
堆栈
当使用堆栈时,这是一个简单的任务。你可以渲染 React Native 暴露的 StatusBar
组件,并设置你的配置。
- 静态
- 动态
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' },
});
import * as React from 'react';
import { View, Text, StatusBar, StyleSheet } from 'react-native';
import { NavigationContainer, useNavigation } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import { Button } from '@react-navigation/elements';
import {
SafeAreaProvider,
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 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.js
和 Screen2.js
)将使用 FocusAwareStatusBar
组件而不是 React Native 的 StatusBar
组件
- 静态
- 动态
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>
);
}
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>
);
}
虽然不是必须的,但你也可以在原生堆栈导航器的屏幕中使用 FocusAwareStatusBar
组件。