Hoang Trung
Hoang Trung

Reputation: 2017

Grid layout with different height items (React Native)

Any idea for implementing a grid layout like the following image.
enter image description here

Upvotes: 3

Views: 7966

Answers (1)

dhorelik
dhorelik

Reputation: 1507

The answer depends on the data you are going to display. I guess this is an infinite list which loads more items on scroll down. If that's the case you need to put 3 ListView-s inside a ScrollView

The markup will look like this:

<View style={styles.wrapper}>
    <ScrollView contentContainerStyle={styles.container}>
        <ListView 
            contentContainerStyle={styles.list} 
            dataSource={this.state.dataSourceColumn1}
        />
        <ListView 
            contentContainerStyle={styles.list} 
            dataSource={this.state.dataSourceColumn2}
        />
        <ListView 
            contentContainerStyle={styles.list} 
            dataSource={this.state.dataSourceColumn3}
        />
    </ScrollView>
</View>

Wrapper View will help you stretch the block to fit the entire area. From the styling point of view you can resolve the task with flexbox:

wrapper: {
    flex: 1
},
container: {
    flexDirection: 'row',
    paddingHorizontal: 5
},
list: {
    flex: 1,
    flexDirection: 'column',
    paddingVertical: 10,
    paddingHorizontal: 5
}

The trick is that we treat every column as a row inside the container. Play around with paddings and alignItems styling to achieve consistent spacing.

Now the tricky part is to handle the dataSource properly. The idea is to have 3 dataSource-s in the component state. This way whenever the data has been fetched, you'll have to go over it manually and split into three sources.

Note that the handy onEndReached that comes with the ListView won't be available here, so you'll have to catch the user reaching the end of the ScrollView in order to know when new fetch is required. But that's a different question which I believe has already been answered elsewhere.

In case the grid is finite and you don't need to throw more items into it, things are simpler. Just split the data the way described above and use 3 View-s with nested items instead of the ListView-s. The reasoning behind that is that ListView comes with a way to set a rowHasChanged condition, which improves performance by never rendering the unchanged list items. You don't really need that if the list is finite.

Upvotes: 5

Related Questions