47

I created a project using CRNA that uses React-Navigation. In one of the screen I have a background image that cover the entire screen and I want to including the header.

Like this image :

enter image description here

Should I just hide the header and use a View that contains the element that I want? If yes will this cause any trouble in case of deep linking?

Solution

React Navigation offers a cool props called headerTransparent that can be used in order to render something under the header.

So the code at the should look like this :

static navigationOptions = {
    headerTransparent: true
  }
t97
  • 721
  • 1
  • 7
  • 19
  • 2
    when i set headerTransparent=true , my back button in header is not working..you have any solution regarding this. – MAhipal Singh Oct 04 '18 at 11:16
  • Can you share your code? and remember is headerTransparent : true not headerTransparent = true! – t97 Oct 05 '18 at 08:39
  • Thank you, you solution is helped me. – HardCoder Mar 22 '21 at 14:56
  • In case anyone else cannot get headerTransparent to work: Make sure you are not using in your code as this will prevent the header from overlapping your content :) – Green Apr 30 '23 at 20:22

11 Answers11

43

Right now with React Navigation 5 we can do something like this:

{
    headerShown: true,
    headerTransparent: true,
}

For example:

const Screen = ({ navigation }) => {
  navigation.setOptions({
    headerShown: true,
    headerTransparent: true,
  });

  return (
    <View>
      <Text>Render your component</Text>
    </View>
  );
};
Abraham
  • 8,525
  • 5
  • 47
  • 53
12

this worked for me :

navigationOptions: {
  ...
  headerTransparent: true,
  headerStyle: {
      backgroundColor: 'transparent',
      ...
  }
}
Shayan Moghadam
  • 1,860
  • 2
  • 10
  • 19
9

To achieve this effect you need to follow those steps:

  1. Change the style of the navigation header with absolute position, transparent background and no border.
  2. Use ImageBackground component as parent component for your screen with the image that you want to use as background.
  3. Add padding top to this ImageBackground to fix the overlapping.

So your code should looks something similar to this:

import React, {Component} from 'react';
import {
  StyleSheet,
  Button,
  ImageBackground,
  Platform,
} from 'react-native';
import {
  createStackNavigator,
} from 'react-navigation';


class HomeScreen extends Component {
  render() {
    return (
        <ImageBackground
            style={styles.container}
            source={require('./images/bg.png')}
        >
          <Button
              onPress={() => {}}
              title="Just a button"
          />
        </ImageBackground>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    paddingTop: Platform.OS === 'ios' ? 60 : 80,
  }
});

const App = createStackNavigator({
  Home: {
    screen: HomeScreen,
    navigationOptions: {
      title: 'Home',
      headerStyle: {
        position: 'absolute',
        backgroundColor: 'transparent',
        zIndex: 100,
        top: 0,
        left: 0,
        right: 0,
        elevation: 0,
        shadowOpacity: 0,
        borderBottomWidth: 0,
      }
    },
  }
})

export default App;
David Schumann
  • 13,380
  • 9
  • 75
  • 96
Naoufal
  • 417
  • 3
  • 6
5

If using React Navigation 6.x, the option is the same headerTransparent:

             <Stack.Screen
                  name="BottomTab"
                  component={BottomTabNavigator}
                  options={{
                    headerTransparent: true,
                  }}
              />
Kasra
  • 1,959
  • 1
  • 19
  • 29
4

Solution:

navigationOptions: {
    headerTransparent: {
      position: 'absolute',
      backgroundColor: 'transparent',
      zIndex: 100,
      top: 0,
      left: 0,
      right: 0
    }
Ali Akram
  • 4,803
  • 3
  • 29
  • 38
3

You need to use headerTransparent and headerShadowVisible otherwise if you just use headerTransparent a shadow will be left. This works with React Navigation 6.x. See de docs here https://reactnavigation.org/docs/native-stack-navigator/#headershadowvisible

<Stack.Screen name='Main' component={Main} 
    options={{ 
        title: 'MainPage',
        headerTransparent: true,
        headerShadowVisible: false
    }} 
/>
JFernandes
  • 31
  • 1
1

I have achieved it setting the navigation options like this:

BirdDetails.navigationOptions = () => {
  return {
    ...NavStyle,
    headerStyle: {
      backgroundColor: 'transparent',
    },
    headerTransparent: {
      position: 'absolute',
    },
    headerLeft: <Back></Back>,
    headerRight: <HeaderDetailsRight></HeaderDetailsRight>,
  };
};
danigonlinea
  • 1,113
  • 1
  • 14
  • 20
1

With V5

<NavigationContainer>
        <Stack.Navigator
            initialRouteName="Home"
            screenOptions={{
                headerShown: true,
                headerTransparent:true
            }}
        >
            <Stack.Screen name="Home" component={HomeScreen}/>
            <Stack.Screen name="Detail" component={DetailScreen}/>
            <Stack.Screen name="Setting" component={SettingScreen}/>
        </Stack.Navigator>
    </NavigationContainer>
CodeZi.pro
  • 229
  • 5
  • 8
0

this worked for me:

headerStyle: {elevation:0, backgroundColor:"transparent"}

set elevation to 0 so there is no shadow.

Qasim Zubair
  • 177
  • 2
  • 3
0

I did it this way, it has one flaw though, in the the background color must be hard-coded. This approach is specifically for ScrollView and starts out transparent becoming opaque (keeping the original text).

Since this was designed for native stack navigator to leverage iOS' large text the headerHeight also needs to be adjusted to the proper values.

  const navigation = useNavigation();
  return (
    <ScrollView
      onLayout={(e) => {
        navigation.setOptions({
          headerStyle: {
            backgroundColor: "transparent",
          },
        });
      }}
      onScroll={(e) => {
        const headerOpacity =
          Math.min(
            Math.max(e.nativeEvent.contentOffset.y, 0) / headerHeight,
            1.0
          ) ?? 0.0;
          navigation.setOptions({
            headerStyle: {
              elevation: headerOpacity,
              backgroundColor: `rgba(255,0,0,${headerOpacity})`,
            },
          });
      }}
      scrollEventThrottle={16}
      contentInsetAdjustmentBehavior="never"
    >
Archimedes Trajano
  • 35,625
  • 19
  • 175
  • 265
0

As of August 2023 and react-navigation v6+, I had to use both headerStyle and headerTransparent:

<Stack.Screen
    name="Home"
    component={Home}
    options={({ navigation }) => ({
        headerStyle: {
            backgroundColor: 'transparent',
        },
        headerTransparent: true,
    })}
/>
jbnunn
  • 6,161
  • 4
  • 40
  • 65