White background flashing when switching screens - React-Navigation v5

12,869

Solution 1

I faced the same issue and dived into an investigation. It seems that the detachment of the screens causes it. I found a few approaches. You can choose one according to your needs. They are the following:

  1. You can specify a view wrapper of the navigator with the same background color as the screens one like:

    <View style={{ flex: 1, backgroundColor: '#YOUR_SCREEN_COLOR' }}>
      // It could be your NavigationContainer or your StackNavigator depends on your goals 
      <Navigator /> 
    </View>
    
  2. You can also specify your screen mode to be modal in the stack view config this prevents the screens from being detached like:

    <StackNavigator.Navigator mode="modal">
      {/*.... Your stack screens ... */}
    </StackNavigator.Navigator>
    
  3. You can add your custom overlay in screenOptions by using the cardOverlay prop:

    cardOverlay: () => (
      <View
        style={{
        flex: 1,
        backgroundColor: '#YOUR_COLOR',
      }}
    />)
    

    Reference: https://reactnavigation.org/docs/stack-navigator/#cardoverlay

  4. You can use the cardStyleInterpolator:

    This allows you to customize the animation transitions when navigating from screen to screen.

    Here are the snippets from the original documentation:

    const forFade = ({ current, closing }) => ({
      cardStyle: {
        opacity: current.progress,
      },
    });
    
    <Stack.Screen
      name="Profile"
      component={Profile}
      options={{ cardStyleInterpolator: forFade }}
    />
    

    Stack Navigator exposes various options to configure the transition animation when a screen is added or removed.

    Reference: https://reactnavigation.org/docs/stack-navigator/#animation-related-options

Solution 2

I am also using StackNavigator in v5, but none of the answers worked for me. That's how I solved the issue:

const navigatorOptions = {
  headerShown: false,
  cardStyle: { backgroundColor: 'transparent' },
  cardStyleInterpolator: ({ current: { progress } }) => ({
    cardStyle: {
      opacity: progress.interpolate({
        inputRange: [0, 1],
        outputRange: [0, 1],
      }),
    },
    overlayStyle: {
      opacity: progress.interpolate({
        inputRange: [0, 1],
        outputRange: [0, 0.5],
        extrapolate: 'clamp',
      }),
    },
  }),
}
 
...

<AppStack.Navigator
  screenOptions={navigatorOptions}
  mode="modal"
>
...

I've found the solution here: https://reactnavigation.org/docs/stack-navigator#transparent-modals

Solution 3

Fixed it by using the DarkTheme for the Navigation Container

import { NavigationContainer, DarkTheme } from '@react-navigation/native';

return (
    <NavigationContainer theme={DarkTheme}>
       {children}
    </NavigationContainer>

Solution 4

An easy fix to this problem that worked for me is to set the sceneContainerStyle in the Tab Navigator like this:

<Tab.Navigator sceneContainerStyle={{backgroundColor: 'black'}}>
...//your screens here
</Tab.Navigator>

Solution 5

const App = () => (
  <View style={styles.appStyle}>
     <Navigation />
  </View>
);
const styles = StyleSheet.create({
  appStyle: { flex: 1, backgroundColor: "#000" }
});
Share:
12,869
haxpanel
Author by

haxpanel

The sky is blue the grass is green the code is clean.

Updated on June 23, 2022

Comments

  • haxpanel
    haxpanel almost 2 years

    I'm migrating a RN project version 4 to 5.

    When switching screens there was an issue with a white background flashing in. In v4 this was solved by setting cardStyle: { backgroundColor: material.containerBgColor } in the StackNavigation options.

    However in v5 I'm unable to fix it with the same approach:

    <Stack.Navigator cardStyle={{ backgroundColor: material.containerBgColor }} ...>

    White flash has come back. Any idea how to fix it? Thanks.

    Update: The structure of the navigation may be important:

    const AppTabNavigator = () => (
      <Tab.Navigator>
        <Tab.Screen name="Home" component={Home} />
        <Stack.Screen name="ScreenD" component={ScreenD} />
        <Stack.Screen name="ScreenE" component={ScreenE} />
        <Stack.Screen name="ScreenF" component={ScreenF} />
      </Tab.Navigator>
    )
    ...
      <Stack.Navigator
        ...
        cardStyle={{ backgroundColor: material.containerBgColor }}
      >
        <Stack.Screen name="Home" component={AppTabNavigator} />
        <Stack.Screen name="ScreenA" component={ScreenA} />
        <Stack.Screen name="ScreenB" component={ScreenB} />
        <Stack.Screen name="ScreenC" component={ScreenC} />
      </Stack.Navigator>
    

    Going from ScreenD to ScreenE does the flashing issue. I'm not sure about the other screens as they don't make any network request / async stuff.