Reputation: 502
I'll provide images of what I'm trying to perform:
One that is how I want it to be and one that shows the problem, finally I'll show the code.
First image (how I want it to be):
Second image (how it looks when I have a third card)
Here is the code:
<ScrollView>
<View style={{ padding: 10 }}>
<View style={{ paddingTop: '5%' }}></View>
<View style={{ flexDirection: 'row', justifyContent: 'space-between' }}>
{this.state.subjects.map(subject => {
return (
<View key={subject.id}>
<TouchableOpacity onPress={() => this.props.navigation.navigate('ViewSubject', { id: subject.id })}>
<ImagedCarouselCard
width={180}
height={180}
text={subject.name}
shadowColor="#051934"
source={{
uri: "http://site.test/" + subject.icon,
}}
/>
</TouchableOpacity>
</View>
)
})}
</View>
<View style={{ paddingTop: '2%' }}></View>
</View>
</ScrollView>
Upvotes: 2
Views: 5619
Reputation: 9
I tried the answer suggested by @MJ Studio
but it did not work out for me, so I tried a work around, I know this is not an ideal solution, but it works for me, hope this is useful to someone else as well.
const renderComponents = () => {
return (
<ScrollView>
<View style={styles.cardwrap}>
<View style={styles.card}>
<Text>Hello 1</Text>
</View>
<View style={styles.card}>
<Text>Hello 2</Text>
</View>
<View style={styles.card}>
<Text>Hello 3</Text>
</View>
<View style={styles.card}>
<Text>Hello 4</Text>
</View>
<View style={styles.card}>
<Text>Hello 5</Text>
</View>
</View>
</ScrollView>
);
};
export default renderComponents;
// . . . . . . . . . Styles . . . . . . . . .
const styles = StyleSheet.create({
cardwrap: {
flexDirection: 'row',
flexWrap: 'wrap',
justifyContent: 'space-between',
marginBottom: 30,
marginHorizontal: 10,
},
card: {
width: '45%',
backgroundColor: 'red',
marginVertical: 10,
paddingVertical: 20,
alignItems: 'center',
},
});
In the above mentioned code, I used flexDirection: 'row'
to make sure that the cards are sequential and flexWrap: 'wrap'
to contain the cards within the view.
Note : Make sure that the card designed is with width which does not span more that 50%
or else it would move to the next row.
Upvotes: 0
Reputation: 1
You can achieve this using Flatlist numColumn ={2} you can follow my snippets.
<FlatList
data={data}
contentContainerStyle={{alignItems:'center'}}
columnWrapperStyle={{ flexWrap: 'wrap'}}
numColumns={2}
renderItem={({item}) => renderItem(item)}
/>
Upvotes: 0
Reputation: 4611
flexWrap
to wrap
in Container stylewidth
of each cards to (screen width - card margin * 3) / 2
This is my functional component example
But using FlatList and set numColumns
to 2 is more useful
FlatList numColumn
const subjects = [
{ id: 1, name: 'Card 1' },
{ id: 2, name: 'Card 2' },
{ id: 3, name: 'Card 3' },
{ id: 4, name: 'Card 4' },
];
const cardGap = 16;
const cardWidth = (Dimensions.get('window').width - cardGap * 3) / 2;
return (
<ScrollView>
<View
style={{
flexDirection: 'row',
flexWrap: 'wrap',
justifyContent: 'center',
}}
>
{subjects.map((subject, i) => {
return (
<View
key={subject.id}
style={{
marginTop: cardGap,
marginLeft: i % 2 !== 0 ? cardGap : 0,
width: cardWidth,
height: 180,
backgroundColor: 'white',
borderRadius: 16,
shadowOpacity: 0.2,
justifyContent: 'center',
alignItems: 'center',
}}
>
<TouchableOpacity>
<Text>{subject.name}</Text>
</TouchableOpacity>
</View>
);
})}
</View>
</ScrollView>
);
You can see flexWrap
docs
Upvotes: 4