Ravi Raj
Ravi Raj

Reputation: 6677

Showing list empty message at the center of the screen in a FlatList using ListHeaderComponent

I am using React-Native version 0.43.0 which does not support ListEmptyComponent of FlatList. Hence I am using ListHeaderComponent to render a view when the list is empty,

import React, { Component } from 'react';
import { Text, View, StyleSheet,FlatList } from 'react-native';

class App extends Component {
  constructor(props) {
    super(props);
    this.state = {
      listData: []
    }
  }
  render() {
    return (
      <View style={styles.container}>
        <FlatList
          renderItem={() => null}
          data={this.state.listData}
          ListHeaderComponent={() => (!this.state.listData.length? 
            <Text style={styles.emptyMessageStyle}>The list is empty</Text>  
            : null)
          }
        />
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex:1
  },
  emptyMessageStyle: {
    textAlign: 'center',
    //My current hack to center it vertically
    //Which does not work as expected
    marginTop: '50%', 
  }
});

enter image description here

As you can see from the image the text is not centered vertically

Any idea how to center it vertically in a FlatList?

I have already tried applying justifyContent, alignItems etc but no use.

This is a link to the snack.expo - https://snack.expo.io/S16dDifZf

Upvotes: 35

Views: 59732

Answers (7)

Thushitha Madusanka
Thushitha Madusanka

Reputation: 31

<FlatList
keyExtractor={(item) => item.id}
  data={flatListItems}
    ListEmptyComponent={<View style= {styles.EmptytextHeader}><Text style={styles.EmptyMassage}>No data found</Text></View>}
             renderItem={({ item }) => {
                        return <View><Text>add Your Data</Text></View>

                        />
                    }}
                />
                
                
   const styles = StyleSheet.create({
    EmptytextHeader: {
        flex:1,
        justifyContent:'center',
        alignItems:'center'
    },
    EmptyMassage: {
       color:'red',
        fontWeight: '700',
        fontSize: 16,
        fontStyle: 'normal',
    },
    });

its working

Upvotes: 3

cristian.nieto.dev
cristian.nieto.dev

Reputation: 183

This resolve for me.

<FlatList
    contentContainerStyle={{ flexGrow: 1,
        justifyContent: "center",
        alignItems: "center"}}
    disableVirtualization={false}
    data={this.state.data}
    renderItem={this.renderItem}
    ListEmptyComponent={this.renderEmptyContainer()}
      />
    }
  />

Upvotes: 10

Patrik Ken
Patrik Ken

Reputation: 71

You must combine props ListEmptyComponent with contentContainerStyle={{flex:1}} flex:1 will set the maximal height in the container and will allow you to center vertically. ie:

<FlatList 
    ...
    contentContainerStyle={customers.length === 0 && styles.centerEmptySet}
    ListEmptyComponent={<EmptySetCustomer />}
/>

Note that you must set a condition to remove flex:1 when list is not empty. To allow scroller.

Hope it will help.

Upvotes: 7

Geng  Jiawen
Geng Jiawen

Reputation: 9154

They fixed ListEmptyComponent in this pr https://github.com/facebook/react-native/pull/18206. But they will ship in 0.56.

UPDATE: Checkout the official doc ListEmptyComponent

Upvotes: 16

Aakash Daga
Aakash Daga

Reputation: 1561

Hope this will help you

<FlatList
    contentContainerStyle={{ flexGrow: 1 }}
    disableVirtualization={false}
    data={this.state.data}
    renderItem={this.renderItem}
    ListEmptyComponent={this.renderEmptyContainer()}
      />
    }
  />

Place your UI in the renderEmptyContainer() method and boom, Empty container will show up whenever your list is empty

Upvotes: 70

Fabrizio Rizzonelli
Fabrizio Rizzonelli

Reputation: 429

As a temporary workaround you can conditionally set a style to the contentContainer to center only the empty set like this

<FlatList 
    contentContainerStyle={customers.length === 0 && styles.centerEmptySet}
    data={customers}
    renderItem={({ item, index }) => (
        /// Your item here
    )}
    keyExtractor={(item, index) => {
        return String(index);
    }}
    ListEmptyComponent={<EmptySetCustomer />}
/>

And styles like this

centerEmptySet: { justifyContent: 'center', alignItems: 'center', height: '100%' }

Then in 2-3 weeks we can update to 0.56 and remove the workaround

Upvotes: 3

raghu
raghu

Reputation: 398

You can add a style to the FlatList.

const styles = StyleSheet.create({
  container: {
    flex:1
  },
  listStyle: {
    justifyContent: 'center'
  },
  emptyMessageStyle: {
    textAlign: 'center',
    }

});

  render() {
    return (
      <View style={styles.container}>
        <FlatList style={styles.listStyle}
          renderItem={() => null}
          data={this.state.listData}
          ListHeaderComponent={() => (!this.state.listData.length ? 
            <Text style={styles.emptyMessageStyle}>The list is empty</Text>  
            : null)}
        />
      </View>
    );
  }  

This will center the items in the list, when the list is not empty. You may have to apply another style (when the list is not empty), if you don't prefer the non empty style.

Link to snack.expo

Another option - without changing FlatList style - conditionally rendering FlatList based on this.state.listData.length

render() {
    return (
      <View style={styles.container}>
        {
          this.state.listData.length?

          (<FlatList 
            renderItem={() => null}
            data={this.state.listData}
          />) 
          :
          (
            <View style={styles.emptyListStyle}>
              <Text style={styles.emptyMessageStyle}>The list is empty</Text>  
            </View>
          )
        }
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex:1
  },
  emptyListStyle: {
    flex: 1,
    justifyContent: 'center'
  },
  emptyMessageStyle: {
    textAlign: 'center',
    }

});

This is the snack.expo

Upvotes: 7

Related Questions