React Native FlatList separator between columns

Viewed 54011

I have a FlatList with multiple columns:

    <FlatList
      numColumns={4}
      ItemSeparatorComponent={this.renderSeparator}
      ...
    </FlatList>

And a line separator:

  renderSeparator = () => (
    <View
      style={{
        backgroundColor: 'red',
        height: 0.5,
      }}
    />
  );

But the separator only appear between rows, not between columns (even if i add width: 0.5

View on expo

9 Answers

Incase anyone runs into this in the future, I discovered an alternative using flexbox.

A FlatList accepts a columnwrapperStyle so a style of justifyContent: 'space-around' would do

and then for the element returned in the renderItem give a flex divisible by 1 so if the numColumns is 2 you'd set the flex for the renderItem to be about 0.45

<FlatList
numColumns={2}
ItemSeparatorComponent={() => (
              <View style={{ backgroundColor: "green", height: 2 }} />
            )}
 columnWrapperStyle={{
       justifyContent: "space-between",
     }}
renderItem={({item, index}) => <View style={{flex: 0.45, height: 120, backgroundColor: '#dedede' }}>
<Text>{index}</Text>
</View>}
/>

I am bit to the party but I ran into same problem and solved this problem by using this renderRow code. I have 2 columns in grid view. Please change column length by replacing X in index % X === 0 and index <= Y where Y is columns-1

renderRow({ item, index }) {
    return (
      <View style={[styles.GridViewContainer, 
                    index % 2 === 0 ? {
                      borderLeftWidth: 1, borderLeftColor: 'black',
                      borderRightWidth: 1, borderRightColor: 'black',} 
                      : 
                      {borderRightWidth: 1, borderRightColor: 'black'}

                      ,{borderBottomWidth: 1, borderBottomColor: 'black'}
                      ,index <= 1 && {borderTopWidth: 1, borderBottomColor: 'black'}
                    ]}
      >

      ... render item code ...
        </View>
    )
  }

I watched your Expo. It is as below.

 1   2   3   4 
---------------
 5   6   7   8 

I assume you want as below.

 1 | 2 | 3 | 4 
---+---+---+---
 5 | 6 | 7 | 8 

To do this, It is not possible with ItemSeparatorComponent only. as Hazim Ali says, use different style per index.

renderItem={({ item, index }) => (
        <Text style={[styles.text, index % 4 !== 0 && {borderLeftWidth: 1, borderLeftColor: 'red'}]}>{item}</Text>
    )}

enter image description here

This is the complete example.

--

But the separator only appear between rows, not between columns

As far as I read the source code, when numColumns > 2, there is no itemseparator between columns. Itemseparator is only between row and row.

Here is example. When numColumns is set 4, four items are grouped to one cell. And one itemSeparator is put between cells.

 1   2   3   4  <- cell1
--------------- <- itemSeparator
 5   6   7   8  <- cell2

Add another view with background color and width using the index value of flatlist

I have 4 values in index so I passed the separator view upto index 3 using index-3.

                     <FlatList
                      data={status_project}
                      horizontal={true}
                      showsHorizontalScrollIndicator={false}
                      keyExtractor={(item, index) => index.toString()}
                      renderItem={({ item, index }) => {
                        return (
                          <>
                            <TouchableOpacity
                              onPress={() => {
                                this.setState({ status_selection: index });
                                console.log("Pressed");
                              }}
                            >
                              <View
                                style={{
                                  marginHorizontal: 2,
                                  paddingVertical: 5,
                                }}
                              >
                                <View
                                  style={{
                                    backgroundColor:
                                      this.state.status_selection === index
                                        ? "#fff"
                                        : "transparent",
                                    paddingVertical: 10,
                                    borderRadius: 8,
                                    width: windowWidth / 4 - 8,
                                    height: 40,
                                    alignItems: "center",
                                  }}
                                >
                                  <Text
                                    style={[
                                      { textAlign: "center", fontWeight: "bold" },
                                      {
                                        color:
                                          this.state.status_selection === index
                                            ? Colors.primary_color
                                            : "black",
                                      },
                                    ]}
                                  >
                                    {item.title}
                                  </Text>
                                </View>
                              </View>
                            </TouchableOpacity>
                            <View
                              style={{
                                backgroundColor:
                                  index - 3 ? Colors.tab_bar_color : "transparent",
                                width: 0.5,
                              }}
                            ></View>
                          </>`
                        );
                      }}
                    />

This will help you:

<FlatList
      data={['1', '2', '3', '4', '5', '6', '7', '8']}
      numColumns={4}
      ItemSeparatorComponent={this.renderSeparator}
      renderItem={({ item ,index}) => (
        <>
        <Text style={styles.text}>{item}</Text>
        <View
                      style={{
                        backgroundColor:
                          index - 3 ? 'red': "transparent",
                        width: 0.5,
                      }}
                    ></View>
                    </>
      )}
    />
Related