Manspof
Manspof

Reputation: 357

react native flatlist 2 items per row , width not equal

I build react native app and I'm trying to make 2 items per row with equal width in flatList. what I get it's 2 items per row but not equal width.

const itemProduct = props => {
return (
    <Button style={style.container} onPress={props.onPress}>
        <View style={style.imageContainer}>
            <LoadingImage resizeMode='contain' resizeMethod='resize' source={props.Image ? { uri: 'https://www.saramashkim.co.il/'+props.Image } : require('../../assets/images/default_no_image.png')} style={style.image} />
        </View>
        <View style={style.textContainer}>
            <Text style={style.productName}>vodka</Text>
            <View style={style.specialOffer}>
                {props.inPromotion ? <Text>special offer</Text> : null}
            </View>

            <View style={style.bottomLine}>
                <Text style={style.costText}>lorem ipos</Text><View style={style.bottomLine}>{props.discount ? <Text style={style.Price}>lorem ipos{parseFloat(Math.round(props.price_per_case * 100) / 100).toFixed(2)}</Text> : null}<Text style={style.discountPrice}>dollar{parseFloat(Math.round(props.price_per_case * ((100 - props.discount) / 100) * 100) / 100).toFixed(2)}</Text></View>
            </View>
        </View>
    </Button>
    )
}

style

const style = StyleSheet.create({
container : {
    backgroundColor: colors.dark_red,
    paddingTop:calcSize(10),
    margin:calcSize(10),
    minWidth:(width-15)/2,

},
imageContainer:{
    flex:1,  
    alignItems:'center'
},
textContainer:{
    flex:2,
    //backgroundColor:'red',
    paddingHorizontal:calcSize(30)
},
image:{ 
    width: calcSize(175), 
    height: calcSize(175) 
},
brandName:{
    color:'#7c7c7c',
    fontFamily:'Poppins-Light',
    fontSize:calcSize(25),
    marginBottom:calcSize(15)
},
productName:{
    color: colors.black,
    fontFamily:'Poppins-Regular',
    fontSize:calcSize(20),
    width:calcSize(300)

},

flatList

<View style={style.list}>
   <FlatList
       refreshing={this.state.refreshing}
       numColumns = {2}
       onRefresh={this.onListRefresh}
       data={products}
       keyExtractor={(o, i) => i.toString()}
       renderItem={this.renderProductListItem}
       ListFooterComponent={() => {
          if ((this.state.products.length < this.state.totalFound || this.state.loading) && !this.state.refreshing)
             return <Spinner style={style.loading} />
             return <View style={style.loading} />
          }}

          ItemSeparatorComponent={() => <View style={style.separator} />} />
   </View>
</View>

list style

list:{
    flex:1,
    flexDirection:'row',
    paddingHorizontal: calcSize(30),
}

photo enter image description here

I want to make 2 item per row with equal width, also into the photo as you can see the text in left not equal to the right so it's issue.

Upvotes: 3

Views: 8071

Answers (2)

Pritish Vaidya
Pritish Vaidya

Reputation: 22189

Right now you've exclusively set the width of the child element as minWidth:(width-15)/2, the margin as margin:calcSize(10), padding for the main container as paddingHorizontal: calcSize(30) which is causing the issue .

If you want to go the minWidth way, then you need to calculate the spacing correctly

minWidth = (screenWidth - (paddingHorizontal * 2) - (margin * 2) - (separatorWidth)) / 2 = (screenWidth - 80) / 2

Since there is no separatorWidth mentioned in the question

  • paddingHorizontal: Setting paddingHorizontal is like setting both of paddingLeft and paddingRight.
  • margin: Setting margin has the same effect as setting each of marginTop, marginLeft, marginBottom, and marginRight.

    list:{
        flex:1,
        paddingHorizontal: calcSize(30),
    },
    container : {
        flex: 1, //<== Either add a height or a flex
        backgroundColor: 'darkred',
        paddingTop:calcSize(10),
        margin:calcSize(10),
        minWidth:(width-80)/2,
    
    },
    

Better approach would be to use height and flex , so that width can be scaled accordingly.

Here's a snack demo

Upvotes: 1

Rajendran Nadar
Rajendran Nadar

Reputation: 5438

Use flexbox with flexbasis and flex grow try this

<View style={{flex: 1, flexDirection: 'row', flexWrap: 'wrap', flexGrow: 0}}>
   <View style={{flexBasis: '50%', height: 50, backgroundColor: 'powderblue'}} />
   <View style={{flexBasis: '50%', height: 50, backgroundColor: 'skyblue'}} />
   <View style={{flexBasis: '50%', height: 50, backgroundColor: 'steelblue'}} />
   <View style={{flexBasis: '50%', height: 50, backgroundColor: 'blue'}} />
</View>

Tested in my android device.

Live demo is over here! Give this a try

If any issue comment that down below

Upvotes: 3

Related Questions