'How to create two columns with space beetwen in react native - flatList
Hi i'm new in React Native.
I am trying to create two columns layout with space beetween using react native component called flatList.
Here is my view Code:
<View style={styles.container}>
<FlatList
data={db}
keyExtractor={ (item, index) => item.id }
numColumns={2}
renderItem={
({item}) => (
<TouchableWithoutFeedback onPress ={() => showItemDetails(item.id)}>
<View style={styles.listItem}>
<Text style={styles.title}>{item.name}</Text>
<Image
style={styles.image}
source={{uri: item.image}}
/>
<Text style={styles.price}>{item.price} zł</Text>
</View>
</TouchableWithoutFeedback>
)
}
/>
</View>
Here is styles:
container: {
flex: 1,
flexDirection: 'row',
justifyContent: 'space-between',
padding: 10,
marginBottom: 40
},
listItem: {
maxWidth: Dimensions.get('window').width /2,
flex:0.5,
backgroundColor: '#fff',
marginBottom: 10,
borderRadius: 4,
},
And result is two columns but without space between. Could you help me resolve this problem ?
Solution 1:[1]
You can give the item itself a width value of 45%
. Also, flatlist has a property called columnWrapperStyle
that you can give the value justifyContent: 'space-between
.
Heres an example:
<FlatList
columnWrapperStyle={{justifyContent: 'space-between'}}
data={ApiData}
numColumns={2}
renderItem={({item}) => {
return (
<item style={{width: '45%'}} />
);
}}
/>
Solution 2:[2]
Use ItemSeparatorComponent for render a compontent between items
Docs: Rendered in between each item, but not at the top or bottom.
<FlatList
data={arrayOfData}
horizontal
ItemSeparatorComponent={
() => <View style={{ width: 16, backgroundColor: 'pink' }}/>
}
renderItem={({ item }) => (
<ItemView product={item} />
)}
/>
If list is vertical and suppose columnCount
is 2
Solution 3:[3]
You have to give the styles.container
to the contentContainerStyle
propety of Flatlist, like so:
<FlatList
data={db}
keyExtractor={ (item, index) => item.id }
contentContainerStyle={styles.container}
numColumns={2}
renderItem={
({item}) => (
<TouchableWithoutFeedback onPress ={() => showItemDetails(item.id)}>
<View style={styles.listItem}>
<Text style={styles.title}>{item.name}</Text>
<Image
style={styles.image}
source={{uri: item.image}}
/>
<Text style={styles.price}>{item.price} z?</Text>
</View>
</TouchableWithoutFeedback>
)
}
/>
Solution 4:[4]
Just add some margin to the style of the list Item.
listItem: {
margin: 10,
}
Solution 5:[5]
I haven't used this library, but adding padding: 10
to listItem styles should help.
Solution 6:[6]
Based on your example it looks like you can add a margin
to your list item styles:
listItem: {
maxWidth: Dimensions.get('window').width /2,
flex:0.5,
backgroundColor: '#fff',
marginBottom: 10,
borderRadius: 4,
margin: 18,
},
Keep in mind that this is equivalent to doing:
listItem: {
maxWidth: Dimensions.get('window').width /2,
flex:0.5,
backgroundColor: '#fff',
marginBottom: 10,
borderRadius: 4,
marginTop: 18,
marginBottom: 18,
marginRight: 18,
marginLeft: 18,
},
Customize to your liking or spec :)
Solution 7:[7]
Assuming your items are flex:1
and no width specified. You can wrap your renderItem with another view that adds the padding if needed
function columnWrappedRenderItemFunction<ItemT>(
renderItem: ListRenderItem<ItemT>,
numColumns: number,
space: FlatListProps<ItemT>["space"],
numberOfItems: number
): FlatListProps<ItemT>["renderItem"] {
return function columnWrappedRenderItem({
index,
...props
}: Parameters<ListRenderItem<ItemT>>[0]): ReturnType<ListRenderItem<ItemT>> {
const needsGapOnLeft = index % numColumns !== 0;
let extraItems = 0;
if (index === numberOfItems - 1) {
extraItems = (numColumns - (numberOfItems % numColumns)) % numColumns;
}
if (needsGapOnLeft) {
return (
<>
<View style={{width:space}} />
{renderItem({ index, ...props })}
{Array.from({ length: extraItems }, (_, k) => (
<View key={"extra_" + k} style={{marginLeft:space, flex:1}} />
))}
</>
);
} else {
return (
<>
{renderItem({ index, ...props })}
{Array.from({ length: extraItems }, (_, k) => (
<View key={"extra_" + k} marginLeft={space} style={{flex:1}} />
))}
</>
);
}
};
}
e.g.
function myRenderItem() { ... }
...
return (<FlatList
...
data={data}
renderItem={
numColumns === 1
? renderItem
: columnWrappedRenderItemFunction(
renderItem,
numColumns,
space,
data.length
)
}
numColumns={numColumns}
ItemSeparatorComponent={() => <View style={{height: space}} />}
/>);
Solution 8:[8]
How to create two columns with equal spacing between items:
<FlatList
data={DATA}
renderItem={renderItem}
keyExtractor={(item) => item.id}
horizontal={false} // you must include this line when using numColumns [per the documentation][1]
numColumns={2} // creates two columns
key={2} // add key to prevent error from being thrown
columnWrapperStyle={{justifyContent: 'space-between'}} // causes items to be equally spaced
>
Also, this will set each column to 1/2 the screen width:
const styles = StyleSheet.create({
item: {
flex: 1/2,
}})
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Luke Melaia |
Solution 2 | Sanjeev |
Solution 3 | Komeyl94 |
Solution 4 | Peyotle |
Solution 5 | Saleel |
Solution 6 | TechnoTim |
Solution 7 | Archimedes Trajano |
Solution 8 | Green |