Queen
Queen

Reputation: 571

Aligning buttons in toolbar using flex

I am new in react native and I really get stuck in aligning a two toolbar buttons for two days! I need to put them in the right part of my tool bar using flex. However, I couldn't do that. Here is the code:

export default class ToolbarHorizontal extends Component {

  // component prop types
  static propTypes = {
    items: React.PropTypes.arrayOf(React.PropTypes.shape({
      active: React.PropTypes.bool,
      name: React.PropTypes.string.isRequired,
      imageSourceActive: React.PropTypes.number.isRequired,
      imageSourceInactive: React.PropTypes.number.isRequired,
      onOpen: PropTypes.func,
    })).isRequired,
    toolbarActiveItem: React.PropTypes.string.isRequired,
    forcedPath: React.PropTypes.bool,
    forcedPathImageSource: React.PropTypes.number,
    tintColor: React.PropTypes.string,
  };

  constructor(props) {
    super();
    this.toolbarActiveIndex = props.items.map((el) => el.name).indexOf(props.toolbarActiveItem);
  }

  render() {
    const { items } = this.props;
    let { toolbarActiveItem } = this.props;
    let { forcedPath } = this.props;
    let { forcedPathImageSource } = this.props;
    let { tintColor } = this.props;
    tintColor = (tintColor) ? tintColor : '#000'; // default value is black
    return (
      <View style={styles.container} >
        <ScrollView
          horizontal={true}
          collapsable={true}
          showsHorizontalScrollIndicator={false}
          showsVerticalScrollIndicator={false}
          style={styles.scroller}
        >
   <View style={styles.componentContainer}>
        { items.map((item, index) => {
            let active = (item.active !== undefined) ? item.active : true; // default value is true
            if (active) {
              return(
                <View key={item.id} style={styles.imageContianer}>
                  {(toolbarActiveItem == item.name) &&
                    <View style={styles.insideImageContainer}>
                      <Image
                        source={item.imageSourceSection}
                        style={styles.item}
                      />
                      <Text size={20} style={{color:tintColor, paddingRight:10}}>{!forcedPath ? item.description : null}</Text>
                    </View>
                  }
                </View>
              );
            }
          }
        )}


<View style={styles.buttomContainer}>
        { items.map((item, index) => {
            //console.log('toolbarActiveItem == item.name:', toolbarActiveItem, '==', item.name);
            let active = (item.active !== undefined) ? item.active : true; // default value is true
            if (active && (!forcedPath || item.isVisibleWhenForcedPath)) {
              return(
                <View key={item.id} >
                  {item.isTouchable && forcedPath && index > 0 &&
                    <Image
                      source={forcedPathImageSource}
                      style={styles.forcedPathImage}
                    />
                  }
                  {item.isTouchable &&
                    <TouchableOpacity onPress={() => {
                      if (!forcedPath) { // when forcedPath, buttons are never touchable
                        if (toolbarActiveItem != item.name) {
                          item.onOpen(item.name);
                          toolbarActiveItem = item.name;
                        }
                        else
                        { // already on opened page, go back if button is pressed again
                          this.props.navigation.goBack();
                        }
                      }
                    }}>
                      {forcedPath &&
                        <Image
                          source={(toolbarActiveItem == item.name) ? item.imageSourceForcedPathActive : index > this.toolbarActiveIndex ? item.imageSourceForcedPathTobevisited : item.imageSourceForcedPathVisited}
                          style={styles.item}
                        />
                      }
                      {!forcedPath &&
                        <Image
                          source={(toolbarActiveItem == item.name) ? item.imageSourceActive : item.imageSourceInactive}
                          style={styles.item}
                        />
                      }
                    </TouchableOpacity>
                  }
                </View>
              );
            }
          }
        )}
          </View>
        </View>

        </ScrollView>
      </View>
    );
  }

}

const styles = StyleSheet.create({
  container: {
    flex:0.16,
    flexDirection:'row' ,

    //backgroundColor: 'transparent',
  },
  componentContainer: {
    flex:1,
    flexDirection:'row',
    alignContent:'center',
    alignItems: 'center',

  },
  imageContianer: {
    flex:1,
    flexDirection:'row',
    alignContent:'center',
    alignItems:'center',

  },
  buttomContainer: {
    flex:1,
    flexDirection:'row',
  //  backgroundColor: '#9b59b6' ,
  },
insideImageContainer: {
  flex:1,
  alignItems:'center',
  flexDirection:'row',
},

  scroller: {
    marginHorizontal: 0,
    marginVertical: 10,
  },
  item: {
    width: 60,
    height: 60,
    //marginRight: 5,
    margin: 2,
  },
  forcedPathImage: {
    flex: 1,
    width: 24,
    height: 36,
    resizeMode: 'contain',
  },
});

In fact the problem is that, any changing in flex value doesn't work in insideImageContainer or imageContianer. Can you help me to fix this issue. Thanks in advance.

Upvotes: 0

Views: 839

Answers (1)

Rob Hogan
Rob Hogan

Reputation: 2624

At a minimum this should be all you need:

Toolbar = () => <View style={styles.container}>
  <View style={styles.componentContainer}>
    <Text>Icon</Text>
    <Text>Title</Text>
  </View>
  <View style={styles.buttomContainer}>
    <Text>Button1</Text>
    <Text>Button2</Text>
  </View>
</View> 

const styles = StyleSheet.create({
  container: {
    flexDirection: 'row'
  },
  componentContainer: {
    flex: 1,
    flexDirection: 'row'
  },
  buttomContainer: {
    flexDirection: 'row'
  }
});

See this running in Expo

The thing to think about when using flex layouts is; which component should take up the spare space? Give that component a flex: 1 property. (And if multiple component should share the same space, split the flex between them).

In this case you don't want your buttomContainer (typo?) to be any bigger than it needs to be. You want the componentContainer to grow (flex) as big as it can and push the buttomContainer to the right.

Upvotes: 2

Related Questions