5

I am using React-Navigation and StackNavigator to implement a navigation bar at the top of my react native app, which shows the app logo centered and a menu button on the right. I cannot get it to take up the complete space of the header container though, there is always a margin of ~20px on the left.

As you can see in my code, I have already applied all kinds of style properties such as margin: 0, padding: 0, alignment: fill and width:100% to headerStyle, headerContainerStyle and the navigation bar component itself, but none of them helped.

App.js:

import React from 'react';
import { StyleSheet, View } from 'react-native';
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';

import {Home} from "components/Home";
import {NavigationBar} from "components/NavigationBar";

const Stack = createStackNavigator();

export default function App() {
  return (
    <NavigationContainer headerStyle={styles.container}>
      <Stack.Navigator
        initialRouteName="Home" headerStyle={styles.container}
        screenOptions={{
                        headerTitleContainerStyle: styles.container,
                        headerTitleStyle: styles.title,
                        headerStyle: styles.header,
                        headerTitle: props => <NavigationBar {...props} />
                      }}>
        <Stack.Screen name="Home" component={Home} />
      </Stack.Navigator>
    </NavigationContainer>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignment: 'fill',
    width: '100%',
    height:'100%',
    // useless
    margin: 0
  },
  title: {
  },
  header: {
    flex: 1,
    justifyContent: 'center',
    backgroundColor: 'red',
    // useless
    padding: 0,
    margin: 0,
    marginLeft: 0,
    alignment: 'fill',
    alignItems: 'center',
    alignContent: 'center'
  }
});

NavigationBar.jsx:

import React from 'react';
import { Button, StyleSheet, View } from 'react-native';

import { CenteredView } from 'shared/view/CenteredView'; // just a wrapper for View
import { FlexImage } from "shared/image/FlexImage"; // just a wrapper for Image
import { PLACEHOLDER } from "assets/images";

export const NavigationBar = (props) => {
    return (
        <View style={styles.barContainer}>
            <View style={{flex: 1, backgroundColor: 'green'}} />
            <CenteredView style={{flex: 2, backgroundColor: 'yellow'}}>
                <FlexImage source={PLACEHOLDER} />
            </CenteredView>
            <CenteredView style={{flex: 1, backgroundColor: 'green'}}>
                <Button title="Menu" color="#000" />
            </CenteredView>
        </View>
    );
}

const styles = StyleSheet.create({
    barContainer: {
        flex: 1,
        flexDirection: 'row',
        backgroundColor: 'orange',
        justifyContent: 'center',
        // useless
        alignment: 'fill',
        width: '100%',
        height: '100%',
        padding: 0,
        margin: 0,
        marginLeft: 0
    }
});

I assigned different colors to the containers and views to demonstrate the issue. The red column is what is wrong:

Margin issue, tested in Chrome's mobile device simulator


UPDATE: I noticed that I can swipe the complete page to the left so that the margin disappears and the very left of the content container (in aqua blue) disappears, leaving a blank area on the right (see picture below). This only works in the mobile device simulator in Chrome. On my Android phone I still have the margin but cannot swipe.

Swiped to the left

stefanS
  • 312
  • 4
  • 17

2 Answers2

7

I fixed the issue by using the header property rather than headerTitle to declare NavigationBar as my custom header component.

export default function App() {
  return (
    <NavigationContainer>
      <Stack.Navigator
        initialRouteName="Home"
        screenOptions={{
                        headerStyle: styles.header,
                        header: props => <NavigationBar {...props} /> // <------- here
                      }}>
        <Stack.Screen name="Home" component={Home} />
      </Stack.Navigator>
    </NavigationContainer>
  );
}

I find the documentation of StackNavigator options a bit confusing. From my understanding, the difference between header and headerTitle is that headerTitle may also be a string and defaults to the scene title if the header component is not available. But that doesn't really explain the differences in layout. In the code example headerTitle is used.

stefanS
  • 312
  • 4
  • 17
0

Tried header Component but content went to the next line, would be glad if someone could suggest a better way to handle this case

enter image description here

Solution: I used headerTitle Component but with a little modification on right padding to workaround this issue.

enter image description here

I would like to suggest React navigation Team to provide more control over styles please.

Osama Malik
  • 267
  • 2
  • 6