Reputation: 334
Just a little styles guidance required. what i need is to make horizontal flat list in which 1st item should be large in height and then other items should be 2 in columns and so on.
i am attaching the images what i have now and what i want.
What i achieved
What i want
And my code
<FlatList
horizontal
data={this.state.entries}
showsHorizontalScrollIndicator={false}
contentContainerStyle={{
}}
renderItem={({ item: rowData }) => {
return (
<TouchableOpacity
key={rowData.title} onPress={() => alert(rowData.title)}>
<Card>
<CardItem cardBody>
<Image source={{ uri: rowData.ImagePath }}
style={{
height: (rowData.id == 1 ? 200 : 90),
width: (rowData.id == 1 ? 200 : 150),
flex: 1
}} />
</CardItem>
</Card>
</TouchableOpacity>
);
}}
keyExtractor={(item, index) => index.toString()}
/>
Anyone help me out. Much appreciated.
Thanks
Upvotes: 1
Views: 8864
Reputation: 383
Actually, I could not find an exact way to do it without modifying data until now.
So basically you need to modify your data from a one-dimensional array to two dimensional and print the data. Check this snack someone implemented a two-dimensional horizontal scroll
I will write for you a function on how to convert the data from one dimensional to two. And you can use it in your project.
const convertToTwoDimesional = (data) => {
const newData = [];
for (let index = 0; index < data.length; index += 2) {
newData.push(data.slice(index, index + 2));
}
return newData;
};
So you can use my function to convert your incoming data to two-dimension, and implement the slack from the link.
If you have any questions please ask.
This answers your question, I do not have any information for a better approach, if you have found any, then please tell me.
PS:
This video also explains good flat-list
** Here is the method implemented in Typescript **
function convertToTwoDimensional<T>(data: Array<T>): T[][] {
const newData = [];
for (let index = 0; index < data.length; index += 2) {
newData.push(data.slice(index, index + 2));
}
return newData;
}
Upvotes: 0
Reputation: 28539
Unfortunately, as you may have already guessed the numColumns
prop will only work on a vertical FlatList.
Multiple columns can only be rendered with horizontal={false} and will zig-zag like a flexWrap layout. Items should all be the same height - masonry layouts are not supported.
The only way to achieve what you want is to combine the items after the first into groups of two.
So if you had an data set like this
let data = [
{ text: 'one' },
{ text: 'two' },
{ text: 'three' },
{ text: 'four' },
{ text: 'five' },
{ text: 'six' }
]
You would need to convert it into something like this, you don't have to do it like this, it is really up to you but this is one possible way.
let data = [
{ text: 'one' },
{ item1: { text: 'two' }, item2: { text: 'three' } },
{ item1: { text: 'four' }, item2: { text: 'five' } },
{ item1: { text: 'six' }},
]
Combining the items into groups of two means that you can fake that you have a grid layout.
Then all the magic happens in your renderItem
function. There if the index is 0, you can show your big image, and then if it isn't you can show the smaller images.
Here is some sample code that should help you understand what I am talking about.
import React, {Component} from 'react';
import { View, StyleSheet, Text, FlatList } from 'react-native';
export default class Screen1 extends React.Component {
state = {
data: [
{ text: 'one' },
{ item1: { text: 'two' }, item2: { text: 'three' } },
{ item1: { text: 'four' }, item2: { text: 'five' } },
{ item1: { text: 'six' }},
]
}
renderItem = ({item, index}) => {
if (index === 0) {
return (
<View style={styles.bigSquare}>
<Text>{item.text}</Text>
</View>
)
} else {
return (
<View>
<View style={styles.smallSquare}>
<Text>{item.item1.text}</Text>
</View>
{item.item2 && <View style={[styles.smallSquare, {backgroundColor: 'red'}]}>
<Text>{item.item2.text}</Text>
</View>}
</View>
)
}
}
keyExtractor = (item, index) => `${index}`;
render() {
return (
<View style={styles.container}>
<FlatList
horizontal={true}
data={this.state.data}
renderItem={this.renderItem}
keyExtractor={this.keyExtractor}
/>
</View>
)
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
bigSquare: {
height: 220,
width: 220,
margin: 10,
backgroundColor: 'yellow',
justifyContent: 'center',
alignItems: 'center'
},
smallSquare: {
height: 100,
width: 100,
margin: 10,
backgroundColor: 'green',
justifyContent: 'center',
alignItems: 'center'
}
});
Here it is in a snack https://snack.expo.io/@andypandy/horizontal-flatlist-with-grid
Upvotes: 1
Reputation: 330
I hope this helps:
<FlatList
horizontal
data={this.state.entries}
contentContainerStyle={{ flexWrap: "wrap", flexDirection: "column" }}
renderItem={({ item: rowData }) => {
return (
<TouchableOpacity>
<Card>
<CardItem cardBody>
<View
style={{
height: rowData.id == 1 ? 200 : 90,
width: rowData.id == 1 ? 200 : 150,
borderWidth: 1,
}}
/>
</CardItem>
</Card>
</TouchableOpacity>
);
}}
/>
Upvotes: 1