React native flexbox - how to do percentages || columns || responsive || grid etc

前端 未结 3 535
自闭症患者
自闭症患者 2020-12-09 20:08

After working with react native on iOS for the last couple of weeks, I seem to have come across some shortcomings of flex styling... Particularly when it comes to \"responsi

相关标签:
3条回答
  • 2020-12-09 20:19

    React Native already has percentage support:

    <View style={[style.parent]}>
        <View style={[style.child, {backgroundColor: '#996666'} ]} />
        <View style={[style.child, {backgroundColor: '#339966'} ]} />
        <View style={[style.child, {backgroundColor: '#996633'} ]} />
        <View style={[style.child, {backgroundColor: '#669933'} ]} />
    </View>
    
    var style = StyleSheet.create({
        parent: {
            width: '100%', 
            flexDirection: 'row', 
            flexWrap: 'wrap'
        },
        child: {
            width: '48%', 
            margin: '1%', 
            aspectRatio: 1,
        }
    })
    

    0 讨论(0)
  • 2020-12-09 20:22

    There may be a better way to achieve this with flexbox, but I usually define "percentage" helpers vw and vh for viewport width and viewport height, named after the CSS viewport size units of measurement:

    import {Dimensions} from 'react-native';
    
    function vw(percentageWidth) {
      return Dimensions.get('window').width * (percentageWidth / 100);
    }
    
    function vh(percentageHeight) {
      return Dimensions.get('window').height * (percentageHeight / 100);
    }
    

    To flow items in a grid, you can then calculate an appropriate size for items, accounting for margins and viewport size:

    const COLUMNS = 3;
    const MARGIN = vw(1);
    const SPACING = (COLUMNS + 1) / COLUMNS * MARGIN;
    
    const grid = {
      flex: 1,
      flexWrap: 'wrap',
      flexDirection: 'row',
      justifyContent: 'flex-start'
    };
    
    const cell = {
      marginLeft: MARGIN,
      marginTop: MARGIN,
      width: vw(100) / COLUMNS - SPACING
    }
    
    return (
      <View style={grid}>
        {this.props.things.map(thing => <View style={cell} />)}
      </View>
    )
    

    You should only use this technique if you have a known and limited number of items - for arbitrary amount of cards, you should use ListView for performance reasons, and split your data set to rows manually.

    0 讨论(0)
  • 2020-12-09 20:45

    You can use justifyContent: 'space-between'

    <View style={styles.feed}>
        <View style={styles.card} />
        <View style={styles.card} />
        <View style={styles.card} />
        <View style={styles.card} />
     </View>
    
    feed: {
     flex: 1,
     flexDirection: 'row',
     flexWrap: 'wrap',
     padding: 16,
     justifyContent: 'space-between'  }
    
    
    card: {
     backgroundColor: 'white',
     width: '48%',
     aspectRatio: 1,
     marginBottom: 16   }
    

    screenshot

    0 讨论(0)
提交回复
热议问题