2

Is there a way to make the vertical flatlist item take full height? Hopefully using flex, without using Dimensions API since my flatlist is rendered inside stack and tab navigation, getting the available height is hard and if notch is present practically impossible to predict.

   <FlatList
  contentContainerStyle={{ flexGrow: 1, backgroundColor: 'pink' }}
  data={data}
  keyExtractor={(item, index) => {
    return item + '';
  }}
  renderItem={({ item }) => {
    return (
      <View
        style={{
          backgroundColor: 'red',
          width: '100%',
        }}
      >
        <Text>{item}</Text>
      </View>
    );
  }}
/>
maximus10
  • 31
  • 2
  • 6

3 Answers3

2

Make sure the main parent Component has a flex value of 1.

Here is the screenshots of an example app:

when items are 8 when items are only two

Modified Example Code:

Here I am keeping the default height as 100, if the number of items is relatively high and their average height becomes less than 100 then I am setting then the height of items to 100 or to the average height.

i.e. if FlatList has a height of 500 and there are 10 items then their average height will be 500/50 = 10 which is too small to accommodate the contents of ListItem, so instead of setting the height to 10 I will switch to 100, on a contrary if there are only 2 items then 500/2= 250, which is bigger than default height of 100, so in this case, I am using the average, i.e. 250.

//import { List, ListItem } from 'react-native-elements';
import React, { useState } from 'react';
import {
  Text,
  View,
  FlatList,
  StyleSheet,
  SafeAreaView,
  StatusBar,
} from 'react-native';

const attendants = [
  {
    courseName: 'comp',
    lecturer: 'Akanbi T.B',
    students: 'Tunde Ajagba',
    date: '10/11/2020',
    no: 1,
  },
  {
    courseName: 'comp',
    lecturer: 'Akanbi T.B',
    students: 'Tunde Ajagba',
    date: '09/11/2020',
    no: 2,
  },
  {
    courseName: 'comp',
    lecturer: 'Akanbi T.B',
    students: 'Tunde Ajagba',
    date: '08/11/2020',
    no: 3,
  },
  {
    courseName: 'comp',
    lecturer: 'Akanbi T.B',
    students: 'Tunde Ajagba',
    date: '08/11/2020',
    no: 3,
  },
  {
    courseName: 'comp',
    lecturer: 'Akanbi T.B',
    students: 'Tunde Ajagba',
    date: '08/11/2020',
    no: 3,
  },
  {
    courseName: 'comp',
    lecturer: 'Akanbi T.B',
    students: 'Tunde Ajagba',
    date: '08/11/2020',
    no: 3,
  },
  {
    courseName: 'comp',
    lecturer: 'Akanbi T.B',
    students: 'Tunde Ajagba',
    date: '08/11/2020',
    no: 3,
  },
  {
    courseName: 'comp',
    lecturer: 'Akanbi T.B',
    students: 'Tunde Ajagba',
    date: '08/11/2020',
    no: 3,
  },
];

const App = () => {
  const [data, setData] = useState(attendants);
  const [layoutHeight, setHeight] = useState(100);

  return (
    <View style={styles.container}>
      <View style={{ flex: 5 }}>
        <FlatList
          onLayout={(e) => {
            setHeight(e.nativeEvent.layout.height);
            console.log(e.nativeEvent.layout.height);
          }}
          style={{ flexGrow: 1, backgroundColor: 'pink' }}
          data={data}
          keyExtractor={(item) => item.no}
          renderItem={({ item }) => (
            <View
              style={{
                height:
                  data.length * 100 < layoutHeight
                    ? Math.floor(layoutHeight / data.length)
                    : 100,
              }}>
              <ListItem
                title={`${item.lecturer} ${item.courseName}`}
                subtitle={item.students}
              />
            </View>
          )}
        />
      </View>
      <View
        style={{
          flex: 1,
          backgroundColor: 'lightgreen',
          justifyContent: 'center',
          alignItems: 'center',
        }}>
        <Text style={[styles.subtitle, { fontSize: 20 }]}>Bottom Bar</Text>
      </View>
    </View>
  );
};

const ListItem = ({ title, subtitle }) => {
  return (
    <View style={styles.listContainer}>
      <Text style={styles.title}>{title}</Text>
      <Text style={styles.subtitle}>{subtitle}</Text>
    </View>
  );
};
const styles = StyleSheet.create({
  container: {
    marginTop: 30,
    flex: 1,
  },
  listContainer: {
    flex: 1,
    backgroundColor: 'teal',
    margin: 5,
    paddingHorizontal: 5,
    borderRadius: 4,
  },
  subtitle: { fontSize: 12, color: 'rgba(0,0,10,0.5)' },
  title: {
    fontSize: 14,
    color: 'white',
    fontWeight: 'bold',
    textAlign: 'cetere',
  },
});

export default App;

Full Working Example Link: Expo Snack

Ketan Ramteke
  • 10,183
  • 2
  • 21
  • 41
  • I need items inside the flatlist to also take full height, in this case item container would cover the available height (pink area). Is this possible without manually setting item height in dp or screen height percentage? – maximus10 Nov 20 '20 at 07:30
1

You might add flexGrow: 2 to the FlatList, and then, wrap the list into a View with flexShrink: 2. Works for me.

0

I used flatlist's onLayout prop like suggested in https://stackoverflow.com/a/63198139/13551249

Basically it will calculate the amount of space that flatlist is using and that height can be used to set height of the item inside flatlist, so item will take full height of the flatlist.

maximus10
  • 31
  • 2
  • 6
  • What if ```FlatList``` has, lets say 200 items, and ```FlatList``` has a height of ```1000px```, how the height will be distributed between those items? – Ketan Ramteke Nov 20 '20 at 09:41
  • In my use case each item is going to take flatlist full height (1000px in your example). Flatlist is scrollable so it's up to you how items inside are going to be big.Flatlist is not going to distribute the sum of 1000px to each item. – maximus10 Nov 23 '20 at 13:03
  • Nice. I thought you were allocating heights dynamically. Thanks to you I got to know about ```onLayout``` :D good question. – Ketan Ramteke Nov 23 '20 at 13:05