45

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.

haxpanel
  • 4,402
  • 4
  • 43
  • 71
  • Did you find the solution for this? I have the same issue – andreicovaciu Apr 11 '20 at 13:00
  • 2
    If I remember correctly, the solution was somewhere in the native level. You can set the app bgcolor in a `plist` file for iOS and `gradle` file in Android. Good luck! – haxpanel Apr 11 '20 at 20:56
  • I managed to fix the glitch by removing all the LayoutAnimation pieces of code. Thanks! – andreicovaciu Apr 17 '20 at 07:08
  • @andreicovaciu For me LayoutAnimation is also causing this, however just removing all LayoutAnimation code seems like a bad solution imo. – JoniVR Dec 23 '20 at 12:42

23 Answers23

61

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

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
nikolay.hristov
  • 739
  • 6
  • 7
  • 2
    Option one worked for me. I wrapped the NavigationContainer inside a view. – Hackman Mar 09 '21 at 06:23
  • 1
    chiming in here, none of these worked for me, react navigator v5, the solution below by marcelo monteiro worked for me – fullStackChris Jul 28 '21 at 08:10
  • 1
    @fullStackChris I don't think it is correct to say that none of the described issues above don't work for you, since the solution which is described by Marcelo Monteiro is based on option 4 (CardStyleInterpolator) - `"4. You can use the cardStyleInterpolator:"` – nikolay.hristov Aug 01 '21 at 12:01
  • its Useful just wrap stacknavigator inside view and add bgcolor to it. – vaibhav gadekar Dec 18 '21 at 13:56
48

Fixed it by using the DarkTheme for the Navigation Container

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

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

23

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

  • Adding onto this, if you want to have this fade animation but retain the vertical fly in, you can replace the opacity card style interpolation with: `cardStyle: { transform: [{ translateY: progress.interpolate({ inputRange: [0, 1], outputRange: [window.height, 0] }), }], },` – Zack Jun 10 '21 at 19:16
13

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>
Ankush Chauhan
  • 1,433
  • 2
  • 17
  • 22
7
const App = () => (
  <View style={styles.appStyle}>
     <Navigation />
  </View>
);
const styles = StyleSheet.create({
  appStyle: { flex: 1, backgroundColor: "#000" }
});
sakshya73
  • 5,570
  • 5
  • 22
  • 41
6

Using react-native-navigation:^6.0.0, I tested everything here but actually the only things that work is to set a theme on the NavigationContainer

theme={{
  colors: {
    background: 'black', 
  },
}}
Jackmekiss
  • 633
  • 5
  • 12
5

I used the solution provided by @jul

<SafeAreaProvider style={{ backgroundColor: "black" }}>

Small difference is that our SafeAreaProvider wraps NavigationContainer at a much higher level.

<SafeAreaProvider style={{ backgroundColor: "black" }}>
   ...
   <NavigationContainer />
   ...
</SafeAreaProvider>

Serves as a default background color without using native modules to set the root background color

j3tan
  • 51
  • 1
  • 1
4

In my case it was due to the default styles of a SafeAreaProvider inside a NavigationContainer. Setting

<SafeAreaProvider style={{ backgroundColor: "black" }}>

did the trick.

jul
  • 1,054
  • 2
  • 11
  • 24
3

I have solved the issue by disabling the sceneAnimationEnabled of the Tab Navigator.

<Tab.Navigator
  sceneAnimationEnabled={false}>
  {...}
</Tab.Navigator>
Roshan Maddumage
  • 130
  • 3
  • 12
2

I solved this by setting lazy={false} in the <Tabs.Navigator> component:

<Tabs.Navigator
    lazy={false}
>
angeldroth
  • 379
  • 4
  • 5
1

cardStyle is an option on the screen, not the navigator.

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

Or

<Stack.Navigator>
  <Stack.Screen
    name="Home"
    component={AppTabNavigator}
    options={{ cardStyle: backgroundColor: material.containerBgColor }}
  />
  {/* ... */}
</Stack.Navigator>

Reference: https://reactnavigation.org/docs/en/next/stack-navigator.html#cardstyle

Probably a better way is to use the theming system to pass your colors rather than specifying it for every navigator: https://reactnavigation.org/docs/en/next/themes.html

satya164
  • 9,464
  • 2
  • 31
  • 42
1

The problem with me was that I had enableScreens() was enabled in my App.tsx.

You have 2 options:

  • Remove the enableScreens() call
  • add detachPreviousScreen: false to your screenOptions of your navigator and enableScreens(true) to your App.tsx
Zerta
  • 85
  • 6
1

for expo you can change backgroundColor in App.json file to #000000.

The background color for your app, behind any of your React views. This is also known as the root view background color.

Ahmed ALABSI
  • 21
  • 1
  • 3
1

Put the outside your NavigationContainer with flex: 1 and backgroundColor with the color you like

Bruno Luiz
  • 64
  • 4
1

I solved this problem doing this in the app.json file: (but i had the same background color on every page)

"expo": {
    "backgroundColor": "#YOUR_COLOR",
    }
1

Just use 'transparentModal'

<Stack.Navigator
    initialRouteName="Home"
    screenOptions={{
      headerShown: false,
      presentation: 'transparentModal',
    }}>
   <Stack screens here/>
  </Stack.Navigator>

Hope it will help

0

I solved this problem with this code: you can also put cardStyleInterpolator in the options property of each <Screen>

const notAnimation = () => ({});

screenOptions={{ cardStyleInterpolator: notAnimation }}>
Husdady
  • 119
  • 1
  • 4
0

Using react-native-navigation:^4.4.4, the issue is resolved by disabling the animation.

const AppNavigator = createStackNavigator(
  {...<YOUR_CONFIG>},
  {
   ...
   defaultNavigationOptions: {animationEnabled: false}, // Add this line
  },
);

No need to worry about backgroundColor

WhaSukGO
  • 575
  • 7
  • 17
0

Try this , it will work - Just wrap the navigator inside a view and give it a background color and don't forget to set flex

0

For me adding cardStyle was enough to fix it.

const navigatorOptions = {
  ...
  cardStyle: { backgroundColor: 'transparent' },
  ...
}
vimuth
  • 5,064
  • 33
  • 79
  • 116
0

Setting the background color merely "hides" the problem. For me, the problem arose when I switched to react-native-navigation:^6.0.0, but it only happened on screens where I was using LayoutAnimation.configureNext() in a useEffect callback (used to trigger effects when a state changes).

What completely solved the problem for me was to put the LayoutAnimation.configureNext() in the callback function that triggers the state change, instead of passively listening to it with useEffect (because it seemed that the useEffect trigger on render + the LayoutAnimation caused the flash).

0

I have solved this issue by wrapping navigationContainer inside the SafeAreaProvider which is imported from react-native-safe-area-context and give background color to it.

<SafeAreaProvider style={{backgroundColor: Colors?.backgroundColor}}>
    <NavigationContainer>
        <StackNavigator />
    </NavigationContainer>
</SafeAreaProvider>

try it if this works fine, then give upvote and tick the answer. Thanks

Hamid khan
  • 105
  • 7
0

This helped me.

<NavigationContainer
        theme={{dark: true, colors: {...DarkTheme.colors, background: "YOUR_COLOR"}}}>
Rok Rak
  • 11
  • 3
  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community May 19 '23 at 22:04