React Navigation default background color
Asked Answered
C

8

33

I'm using react-navigation and stack-navigator to manage my screens.

Platforms I'm using:

  • Android
  • React Native: 0.47.1
  • React Navigation: 1.0.0-beta.11
  • Emulator and Device

I have a screen, which acts as a modal form but it is really a full screen. Why is it important the part of "acts as a modal form"? That's because it is kind of modal menu with some options and WITH A TRANSPARENT BACKGROUND COLOR.

This is what I expect:

enter image description here

But what I'm getting is this:

enter image description here

As you can see, in the second example the background color is completely replaced or the components previously loaded is unmounted so the effect I want to acchieve is lost. The idea is to be able to navigate to this screen like any other screen.

If it is not posible to accomplish using react-navigation, what other way can I take to do so?

This component executes actions (redux) since is a cross app component and encapsulates lot of mechanisms and logic inside, that's why I can't use it as a PureComponent relaying on the component which makes use of this one. At least, making this Component as PureComponent would force me to replicate many mechanisms and logic in many other components.

For the sake of the question, and to avoid making the question enormous, both screens have exactly the same style, but the one pushed through StackNavigation replaces the backgroundColor, or unmounts the previus screen.

This is what I've have so far:

//PlaylistSelector.js
render() {
  //Just a full size empty screen to check and avoid bugs
  //Using red instead of transparent, works

  return (
    <View style={{ flex: 1, backgroundColor: 'transparent' }}>
    </View>
  );
}

//Navigator.js
import { StackNavigator } from 'react-navigation';

import Album from './Album'; //This is the screen I expect to keep at the background
import PlaylistSelector from './PlaylistSelector';

const AppNavigator = StackNavigator(
    {
        ...moreScreens,
        Album: { screen: Album },
        PlaylistSelector: {
            screen: PlaylistSelector,
            navigationOptions: {
                style: { backgroundColor: 'red' } //Does not work, red is just to ilustrate, should be transparent,
                cardStyle: { //Does not work,
                    backgroundColor: 'transparent',
                },
                bodyStyle: { //Does not work,
                    backgroundColor: 'transparent',
                },
            }
        }
    },
    {
        initialRouteName: 'Splash',
        headerMode: 'none',
        cardStyle: { //Does not work
            backgroundColor: 'transparent',
        },
        transitionConfig: (): Object => ({ //Does not work
            containerStyle: {
                backgroundColor: 'transparent',
            },
        }),
    }
);

export default AppNavigator;
Courtnay answered 14/1, 2018 at 19:28 Comment(1)
I just managed to solve it using containerStyle:{backgroundColor: 'transparent'} turns out I was editing the wrong stackNavigator as I'm using nested ones.Nato
S
99

This was really changed in latest React Navigation versions. See

https://reactnavigation.org/docs/themes/

For example

import * as React from 'react';
import { NavigationContainer, DefaultTheme } from '@react-navigation/native';

const MyTheme = {
  ...DefaultTheme,
  colors: {
    ...DefaultTheme.colors,
    background: 'red'
  },
};

export default function App() {
  return (
    <NavigationContainer theme={MyTheme}>{/* content */}</NavigationContainer>
  );
}
Subtreasury answered 22/3, 2020 at 16:1 Comment(2)
perfect for react-native 5.0Godless
My app is using dark colors and I was getting white flicker during screen transition, using this removed the white flicker, thank you.Roguish
A
24

There's a solution in react-navigation v6.x

Setting cardStyle: {backgroundColor: 'transparent'} on screenOptions prop for the Stack Navigator didn't work for me.

But, with the help of this Github issue page, I found a solution that sets a default background color for our NavigatorContainer:

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

...

const navTheme = {
  ...DefaultTheme,
  colors: {
    ...DefaultTheme.colors,
    background: 'transparent',
  },
};

...

return (
    <NavigationContainer
      theme={navTheme}
...

There we can change 'transparent' to anything we want.

Anabolism answered 25/11, 2021 at 22:6 Comment(0)
A
6

With react-navigation v3.x You can use the transparentCard pro:

const MainNavigator = createStackNavigator(
  {
    BottomTabs: {
      screen: BottomTabsStack,
    },
    Modal: {
      screen: ModalScreen,
    }
  },
  {
    headerMode: 'none',
    mode: 'modal',
    transparentCard: true,
    cardStyle: { opacity: 1 } //This prop is necessary for eventually issue.
  }
);

You can find a complete example below:

https://snack.expo.io/@cristiankmb/stacks-in-tabs-with-header-options-with-modal

Andy answered 9/4, 2019 at 17:21 Comment(1)
This should the marked as the right answer. This is a Snack demo of Modal from ReactNavigation doc. I tried applying the above config & it did really work.Upholstery
Z
1

Add opacity:

cardStyle: {
  backgroundColor: "transparent",
  opacity: 1
}
Zackzackariah answered 14/8, 2018 at 7:23 Comment(0)
G
1

Just throwing what seem most straight forward to me, e.g. setting a headerBackground on screenOptions:

    <Stack.Navigator
      headerMode={"float"}
      screenOptions={{
        headerBackground: () => <View style={{flex: 1, backgroundColor: themeContext.background}} />,
        backgroundColor: themeContext.background
      }}
    >

This doesn't work with transparent headers tho, which might actually be what lead you here in the first place. In that case simply wrap your whole app container into a View like this.

export default function App() {
  return (
    <View style={{flex: 1, backgroundColor: 'red'}}>
      <NavigationContainer linking={linkingConfig}>
        <StatusBar />
        <ApolloProvider client={client}>
          <Provider store={store}>
            <Navigator />
          </Provider>
        </ApolloProvider>
      </NavigationContainer>
    </View>
  )
}

Obviously you want to extract that into it's own (styled) component instead :)

And if you're using Expo, and don't have a seperate dark theme, you can simply set backgroundColor in your app.json.

Gesualdo answered 21/1, 2021 at 1:40 Comment(0)
D
1

You can do this by setting the 'contentStyle' property inside 'options' with your preferred color . For example see this -

<NavigationContainer >
  <Stack.Navigator>
    <Stack.Screen
      name="Home"
      component={HomeScreen}
      options={{ contentStyle:{backgroundColor: "white",} }}
    />

The above code sets the background color of the screen to "white".

Deglutition answered 17/5, 2023 at 10:24 Comment(0)
M
0

As of [email protected] there is a config option transparentCard that makes this possible.

const RootNavigator = createStackNavigator(
  {
    App,
    YourModal,
  },
  {
    headerMode: 'none',
    mode: 'modal',
    transparentCard: true,
  },
);

This won't blur the background for you; it will just make it transparent. To properly blur it, you'll need to do something like this. Make sure you start the background way above the top edge of the screen, since the card will animate in from the bottom, and you probably want the screen to gradually blur instead of the opacity having a sharp edge as it animates in.

Mong answered 5/11, 2018 at 14:36 Comment(0)
W
0

this way worked for me:

const MyDrawerNavigator = createStackNavigator(
    {
        screen1: {
            screen: screen1,
        },
        screen2: {
            screen: screen2,
        },
    },
    {
        navigationOptions: () => ({
            cardStyle: {
                backgroundColor: "rgba(0,0,0,0.5)",
            },
        }),
    }

);
Wolves answered 22/1, 2020 at 15:33 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.