0

I have a dynamic flatlist with values that should be rendered in the horizontal list with 3 columns. But, I am not able to make it display as I wanted.

I am trying the code as follow,

    let data = ["item1", "item2", "item3", "item4", "item5", "item6", "item7", "item8"];
    const { width } = Dimensions.get('window');
    const itemWidth = (width - 12) / 3;

           <FlatList
                    columnWrapperStyle={{ justifyContent: 'space-around', alignItems: 'flex-start' }}
                    numColumns={3}
                    data={data}
                    showsVerticalScrollIndicator={false}
                    showsHorizontalScrollIndicator
                    keyExtractor={(item, index) => `${index}${item}`}
                    renderItem={(item) => {
                        return (
                            <View style={{ flex: 1, backgroundColor: '#ddd', minWidth: itemWidth, maxWidth: itemWidth }}>
                                <Text >
                                    Hello World
                            </Text>
                            </View>
                        );
                    }}
                />

But, the output is not as I wanted.

Let say, if the list is the length of multiple of 3 like 6,9,12 it works as I wanted.

But, if the list has length 8 first two rows are rendered okay. But, the third row is giving full space to the remaining two items. Which I don't want.

Currently i am geeting output as followcurrent output image

But the output should be like, enter image description here

Can anyone suggest a workaround?

Thanks.

Jay Mungara
  • 6,663
  • 2
  • 27
  • 49

2 Answers2

0

See i can provide you one logical solution, and i'm assuming you want to plot the text inside the Flatlist. For this kind of scenarios, you would need to append an empty div for the respective empty slots.

If you want the numOfColumns to be 3,

let data = ["item1", "item2", "item3", "item4", "item5", "item6", "item7", "item8"];

First check the remainder and num of rows to be added by

let numOfRowsToBeAdded = 3-(data.length%3);
// here im ommitting if we get 0 as remainder as its not required
if(numOfRowsToBeAdded){
for(let i=0;i<numOfRowsToBeAdded;i++){
data.push(null);
}
}

Hope you got the logic. feel free for doubts. ill help

Gaurav Roy
  • 11,175
  • 3
  • 24
  • 45
0

Since you calculate itemWidth manually, you can use justify: flex-end for your columnWrapperStyle and then add a marginRight: 6 to every first and second item in every row:

renderItem={(item, index) => {
  const isThirdColumn = (index + 1) % 3 === 0;
  const marginRight = isThirdColumn ? 0 : 6;

  return (
    <View style={{ marginRight, ...otherStyles }}>
Marek Lisik
  • 2,003
  • 1
  • 8
  • 17