メインコンテンツに移動
バージョン: 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フックを使用し、ラッパーコンポーネントを作成することでこれを達成できます。

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の両方)はReact NativeのStatusBarコンポーネントではなくFocusAwareStatusBarコンポーネントを使用します。

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コンポーネントを使用することができます。