最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to align child views to left with even space in React-Native? - Stack Overflow

programmeradmin0浏览0评论

I'm trying to create a menu for my application in React-Native which should have multiple icons in the below way

The icons should be in the same row and wrapped so that if screen is bigger more icons will be on the same row.

My current code is as follows

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

export default class App extends React.Component {
  render() {
    return (
      <View style={styles.container}>
        <View style={styles.box}></View>
        <View style={styles.box}></View>
        <View style={styles.box}></View>
        <View style={styles.box}></View>
        <View style={styles.box}></View>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'space-evenly',
    flexDirection: 'row',
    flexWrap: 'wrap',
    paddingTop: 40
  },
  box: {
    width: 100,
    height: 100,
    backgroundColor: 'aqua',
    margin: 10,
  }
});

The current output is as below

The children count may change in the future but i need to have spacing on the sides, using flex-start will give the below output which is wrong.i want to have spacing in both sides as well.

How do i align it to left and have the items with even space around as the image above ?

I'm trying to create a menu for my application in React-Native which should have multiple icons in the below way

The icons should be in the same row and wrapped so that if screen is bigger more icons will be on the same row.

My current code is as follows

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

export default class App extends React.Component {
  render() {
    return (
      <View style={styles.container}>
        <View style={styles.box}></View>
        <View style={styles.box}></View>
        <View style={styles.box}></View>
        <View style={styles.box}></View>
        <View style={styles.box}></View>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'space-evenly',
    flexDirection: 'row',
    flexWrap: 'wrap',
    paddingTop: 40
  },
  box: {
    width: 100,
    height: 100,
    backgroundColor: 'aqua',
    margin: 10,
  }
});

The current output is as below

The children count may change in the future but i need to have spacing on the sides, using flex-start will give the below output which is wrong.i want to have spacing in both sides as well.

How do i align it to left and have the items with even space around as the image above ?

Share Improve this question edited Mar 7, 2019 at 5:16 Guruparan Giritharan asked Mar 7, 2019 at 4:57 Guruparan GiritharanGuruparan Giritharan 16.4k4 gold badges29 silver badges52 bronze badges 5
  • alignItems: 'center' would center the blocks. Change it to alignItems: 'left' and it should align to the left – Aniket G Commented Mar 7, 2019 at 5:04
  • its react-native and left is not supported :) – Guruparan Giritharan Commented Mar 7, 2019 at 5:05
  • Right. Change justifyContent: 'space-evenly' to justifyContent: 'flex-start' stackoverflow./questions/36008969/… – Aniket G Commented Mar 7, 2019 at 5:06
  • Possible duplicate of How to justify (left, right, center) each child independently? – Aniket G Commented Mar 7, 2019 at 5:07
  • @AniketG flext-start i'm trying to use the same row so flex start will have more space at the right which is the problem, as this is the same row its not a duplicate – Guruparan Giritharan Commented Mar 7, 2019 at 5:10
Add a ment  | 

3 Answers 3

Reset to default 3

for Box use Dimensions, Based on screen width divide box width

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'flex-start',
    flexDirection: 'row',
    flexWrap: 'wrap',
    paddingTop: 40
   },
  box: {
    width: (Dimensions.get('window').width / 3) - 20, /* minus some value for adjust the gap between boxes */
    height: 100,
    backgroundColor: 'aqua',
    margin: 10,
  }
});

One option is to add extra 'fake' boxes which will fill the available space in last row:

<View style={styles.box}></View>
<View style={styles.box}></View>
<View style={styles.box}></View>
<View style={styles.box}></View>
<View style={styles.box}></View>
<View style={[styles.box, styles.boxFake]}></View>
<View style={[styles.box, styles.boxFake]}></View>
<View style={[styles.box, styles.boxFake]}></View>
<View style={[styles.box, styles.boxFake]}></View>
<View style={[styles.box, styles.boxFake]}></View>

// reset all styles like backgroundColor, border, etc.
const styles = StyleSheet.create({
  boxFake: {
    backgroundColor: 'transparent'
  }
});

You can easy calculate the number of necessary 'fake' boxes by the formula:

fakeBoxes = boxesPerRow - totalBoxes % boxesPerRow

I took a different approach by using another view as a wrapper and doing the calculation of its width, this is easier to decide the column widths. The only problem is that we should know the width of the item, wont be a problem in my case. The code will be as below.

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

export default class App extends React.Component {

  constructor(props) {
    super(props);
    this.state = {
      width: 110
    };
  }

  render() {
    //width of child is 110
    const width = `${100 / parseInt(this.state.width / 110)}%`;
    return (
      <ScrollView>
        <View style={styles.container} onLayout={this.onLayout.bind(this)}>
          <View style={[styles.wrapper, { width: width }]}>
            <View style={styles.box}></View>
          </View>
          <View style={[styles.wrapper, { width: width }]}>
            <View style={styles.box}></View>
          </View>
          <View style={[styles.wrapper, { width: width }]}>
            <View style={styles.box}></View>
          </View>
          <View style={[styles.wrapper, { width: width }]}>
            <View style={styles.box}></View>
          </View>
          <View style={[styles.wrapper, { width: width }]}>
            <View style={styles.box}></View>
          </View>
        </View>
      </ScrollView>
    );
  }

  onLayout(e) {
    if (this.state.width !== e.nativeEvent.layout.width) {
      this.setState({
        width: e.nativeEvent.layout.width
      })
    }
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'flex-start',
    justifyContent: 'flex-start',
    flexDirection: 'row',
    flexWrap: 'wrap',
    paddingTop: 40
  },
  box: {
    width: 100,
    height: 100,
    backgroundColor: 'green',
  },
  wrapper: {
    marginVertical: 10, alignItems: 'center'
  }
});
发布评论

评论列表(0)

  1. 暂无评论