React native: How to make horizontal scroll but data is divided to 4 rows

2.2k Views Asked by At

I need to scroll my items horizontally but my data is divided to 4 rows every row contain 4 items. and I can scroll horizontally so the next 16 item come to the screen.

when using numColumns={4} it works if

horizontal={false}

but with

horizontal={true}

I can't specify numColumns attr.

Should I use SectionList instead of FlatList ?

and how it could be implemented ?

let items = [
    { id: 1, title: '1', price: '20' },
    { id: 2, title: '2', price: '16' },
    { id: 3, title: '3', price: '92' },
    { id: 4, title: '4', price: '93' },
    { id: 5, title: '5', price: '20' },
    { id: 6, title: '6', price: '16' },
    { id: 7, title: '7', price: '92' },
    { id: 8, title: '8', price: '93' },
    { id: 9, title: 'Grilled Steak', price: '20' },
    { id: 10, title: 'Pappas', price: '16' },
    { id: 11, title: 'Ciccione', price: '92' },
    { id: 12, title: 'Gyros Melt', price: '93' },
    { id: 13, title: 'Grilled Steak', price: '20' },
    { id: 14, title: 'Pappas', price: '16' },
    { id: 15, title: 'Ciccione', price: '92' },
    { id: 16, title: 'Gyros Melt', price: '93' },
];

<FlatList
    keyExtractor={item => item.id}
    data={items}
    horizontal
    numColumns={4}
    renderItem={({ item }) => <Text>{item.title}</Text>}
/>
2

There are 2 best solutions below

0
Andrew On BEST ANSWER

Unfortunately FlatList doesn't support a number of columns when it is horizontal.

https://facebook.github.io/react-native/docs/flatlist#numcolumns

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.

However, you could group your data so that for every cell in a horizontal FlatList 4 items are rendered.

let items = [
    [ { id: 1, title: '1', price: '20' },
    { id: 2, title: '2', price: '16' },
    { id: 3, title: '3', price: '92' },
    { id: 4, title: '4', price: '93' } ],
    [ { id: 5, title: '5', price: '20' },
    { id: 6, title: '6', price: '16' },
    { id: 7, title: '7', price: '92' },
    { id: 8, title: '8', price: '93' } ],
    [ { id: 9, title: 'Grilled Steak', price: '20' },
    { id: 10, title: 'Pappas', price: '16' },
    { id: 11, title: 'Ciccione', price: '92' },
    { id: 12, title: 'Gyros Melt', price: '93' } ],
    [ { id: 13, title: 'Grilled Steak', price: '20' },
    { id: 14, title: 'Pappas', price: '16' },
    { id: 15, title: 'Ciccione', price: '92' },
    { id: 16, title: 'Gyros Melt', price: '93' } ]
];

Then update your renderItem so that it handles the increased input, something like this.

 renderItem = ({item}) => {
   return item.map(i => <Text>{i.title}</Text>)
 }
0
Malik Abdullah On

I have the same issue with same scenario. making group data is quite a bad practice in case you have long array. so I play with styles of flatlist and I was successful. following is my code if you can take advantage out of it:

  <ScrollView showsHorizontalScrollIndicator={false} horizontal={true} style={styles.flatListContainer}>
                  <FlatList
                    showsHorizontalScrollIndicator={false}
                    data={item.items}
                    numColumns={4}
                    renderItem={_showData}
                    columnWrapperStyle={styles.flatListColumnWraper}
                    keyExtractor={(item) => item.key}
                    style={styles.flatListDataContainer}
                    scrollEnabled={false}
                    contentContainerStyle={
                      styles.flatListContentContainerStyle
                    }
                  />
                </ScrollView>


    flatListContainer: {
marginTop: height(2),
height:height(60),
paddingVertical:height(2)
 },
flatListDataContainer: {
alignSelf: 'center',
},
 flatListContentContainerStyle: {
alignSelf: 'center',
flexDirection: 'row',
justifyContent: 'space-evenly',
},
flatListColumnWraper:{
 flexDirection: 'column',
 },