bleepmeh
bleepmeh

Reputation: 1037

How to horizontally center a component while there are other components in the same row?

I'm trying to mimic a stack navigation header like below: enter image description here

where the title is perfectly centered while there's a return button in the same row on the left.

I have tried to use justifyContent: 'space-between' with an empty View on the right side but the title will be off center to the right a bit. How should I approach this?

my renderHeader function:

  _renderHeader = () => {
    return (
      <View style={styles.headerAbsolute}>
        <View style={styles.bar}>
          <ButtonBack
            text={"Resumes"}
            onPress={() => this._onNavBackHandler()}
          />
          {true ? (
            <Text style={styles.headingFixed}>{this.state.title}</Text>
          ) : ( null )}
          <View/>
        </View>
      </View>
    )
  }

These are the styles:

  bar: {
    height: 55,
    flexDirection: "row",
    alignItems: 'flex-end',
    justifyContent: 'space-between',
    paddingHorizontal: 10,
    paddingBottom: 5,
  },
  headingFixed: {
    fontSize: TITLE_TERTIARY,
    fontWeight: 'bold',
    color: COLOR_DARK_SECONDARY,
    backgroundColor: 'transparent', 
  },

Upvotes: 8

Views: 35897

Answers (2)

Manoj Prabhakar
Manoj Prabhakar

Reputation: 1016

I will make use of Flex here. Please note that i used borderWidth in the below example only for reference to show how it looks.

I will have flexDirection as row and i will give a flex: 1 to all the views inside

App.js

import React, { Component } from 'react';
import {
  View,
  Text
}
from 'react-native';

class App extends Component{
  render(){
    return(
      <View>
        <View style={styles.navBar}>
          <View style={styles.itemStyle}>
            <Text style={{fontSize: 18, color: 'blue'}}>Resumes</Text>
          </View>
          <View style={styles.itemStyle}>
            <Text style={{fontSize: 20, color: 'blue'}}>Settings</Text>
          </View>
          <View style={styles.itemStyle}></View>
        </View>

      </View>
    )
  }
}

const styles = {
  navBar: {
    marginTop: 42,
    height: 36,
    flexDirection: 'row',
    alignItems: 'center'
  },
  itemStyle: {
    flex: 1,
    height: 36,
    alignItems: 'center',
    justifyContent: 'center',
    borderWidth: 1
  }
}

export default App;

You can play around in the inside views. Move the buttonBack inside one of the child views.

Comp

Upvotes: 16

NiFi
NiFi

Reputation: 2458

I can think of two ways to accomplish this, but neither seems quite ideal.

The first way is using a transparent element with fixed width and justifyContent: 'space-between', as you indicated:

<View style={{flexDirection: 'row', justifyContent: 'space-between'}}>
  <Text style={{width: 80}}>left</Text>
  <Text>center</Text>
  <Text style={{width: 80, color: 'transparent'}}>right</Text>
</View>

Setting a fixed width to the elements on each side will cause the middle element to center horizontally.

An alternative approach is using absolute styling. Using percentages with left and right requires React Native >= 0.42.

<View>
  <Text>Left</Text>
  <Text style={{position: 'absolute', width: 50, left: '50%', marginLeft: -25}}>Center</Text>
</View>

Upvotes: 3

Related Questions