cromestant
cromestant

Reputation: 660

React native layout misbehaving

I am trying to learn React native with Ignite. Been fighting with the layout. Here is my main container render function:

render () {
return (
  <View style={styles.mainContainer}>
    <Image source={Images.background} style={styles.backgroundImage} resizeMode='stretch' />
    <View style={[styles.container]}>
      <View style={styles.section} >
        {/* <Image source={Images.ready} />*/}
        <Text style={styles.sectionText}>
          Tap to randomly choose your training task. Slack off for 5
        </Text>
      </View>

      <View style={styles.centered}>
        <TouchableOpacity onPress={this._onPressButton}>
          <Image source={Images.launch} style={styles.logo} />
        </TouchableOpacity>
      </View>
    </View>
    <View style={[styles.bottom]}>
      <View >
        <BottomBar />
      </View>
    </View>
  </View>
)
}

In particular, the last sibling of the container has a view with a BottomBar component.The bottom style does this:

bottom: {
      justifyContent: 'flex-end',
      marginBottom: Metrics.baseMargin
  }

the BottomBar component:

import React, { Component } from 'react'
// import PropTypes from 'prop-types';
import { View, Text, TouchableOpacity } from 'react-native'
import styles from './Styles/BottomBarStyle'

import Icon from 'react-native-vector-icons/FontAwesome'

export default class BottomBar extends Component {
  // // Prop type warnings
  // static propTypes = {
  //   someProperty: PropTypes.object,
  //   someSetting: PropTypes.bool.isRequired,
  // }
  //
  // // Defaults for props
  // static defaultProps = {
  //   someSetting: false
  // }

  render () {
    console.tron.log('rendering my component')
    console.tron.log('Bottom bar styles: \n',styles)
    return (
      <View style={[styles.iconsContainer, styles.debugGreen]}>
        <TouchableOpacity style={[styles.icons,styles.debugYellow]} onPress={()=>{console.tron.log('rocket')}} >
          <Icon style={styles.icons} name='rocket' size={40} color='white' />
        </TouchableOpacity>
        <TouchableOpacity style={styles.button} onPress={ ()=>{console.tron.log('send')} }>
          <Icon style={styles.icons} name='send' size={40} color='white' />
        </TouchableOpacity>
      </View>
    )
  }
}

the styles associated with it:

import { StyleSheet } from 'react-native'
import DebugStyles from '../../Themes/DebugStyles'
import { Metrics } from '../../Themes/'



export default StyleSheet.create({
  ...DebugStyles,
  iconsContainer: {
    flex: 1,
    flexDirection: 'row',
    justifyContent: 'space-between',
    height: 45,
    borderRadius: 5,
    marginHorizontal: Metrics.section,
    marginVertical: Metrics.baseMargin
  },
  icons:{
    height: 45

    }

})

The issue I have, is that if I saw that bottomBar component for a Rounded button as such:

import React, { Component } from 'react'
import PropTypes from 'prop-types'
import { TouchableOpacity, Text } from 'react-native'
import styles from './Styles/RoundedButtonStyles'
import ExamplesRegistry from '../Services/ExamplesRegistry'

// Note that this file (App/Components/RoundedButton) needs to be
// imported in your app somewhere, otherwise your component won't be
// compiled and added to the examples dev screen.

// Ignore in coverage report
/* istanbul ignore next */
ExamplesRegistry.addComponentExample('Rounded Button', () =>
  <RoundedButton
    text='real buttons have curves'
    onPress={() => window.alert('Rounded Button Pressed!')}
  />
)
console.tron.log('Rounded button style: ',styles)
export default class RoundedButton extends Component {
  static propTypes = {
    onPress: PropTypes.func,
    text: PropTypes.string,
    children: PropTypes.string,
    navigator: PropTypes.object
  }

  getText () {
    const buttonText = this.props.text || this.props.children || ''
    return buttonText.toUpperCase()
  }

  render () {
    console.tron.log('roundedButton styles:', styles)
    return (
      <TouchableOpacity style={styles.button} onPress={this.props.onPress}>
        <Text style={styles.buttonText}>{this.getText()}</Text>
      </TouchableOpacity>
    )
  }
}

with its styles:

import { StyleSheet } from 'react-native'
    import { Fonts, Colors, Metrics } from '../../Themes/'

    export default StyleSheet.create({
      button: {
        height: 45,
        borderRadius: 5,
        marginHorizontal: Metrics.section,
        marginVertical: Metrics.baseMargin,
        backgroundColor: Colors.fire,
        justifyContent: 'center'
      },
      buttonText: {
        color: Colors.snow,
        textAlign: 'center',
        fontWeight: 'bold',
        fontSize: Fonts.size.medium,
        marginVertical: Metrics.baseMargin
      }
    })

I get the expected view :

expected positioning

However, with my BottomBar component I get:

Shifted down

One thing to notice is that the debugGreen style is just a border that should wrap around my BottomBar component and it is shown flat, but the icons within it render lower, and the debugYellow styled box around the icon is shown around the icon as expected, just shifted a whole way down.

Upvotes: 0

Views: 274

Answers (1)

hong developer
hong developer

Reputation: 13926

If your mainContainer's view is flex : 1 or height : 100%, you should divide the child's height by 8:2 or the flex by 8:2.

Example

<View style={styles.mainContainer}> // flex: 1
  <View style={styles.container}> // flex : 0.8
...
  </View>
    <View style={styles.bottom}> // flex : 0.2
        <BottomBar />
    </View>
</View>

Upvotes: 1

Related Questions