react-native icon indicating copy to clipboard operation
react-native copied to clipboard

Unable to flex FlatList children to grow to full height when space available

Open fredrivett opened this issue 4 years ago • 5 comments

Description

(Note: This was originally asked on Stack Overflow, but it seems there isn't an existing solution, so filing this as a bug here).

I'm using FlatList to render a bunch of items stacked on top of each other.

This works fine, I've managed to make the FlatList itself expand its height to fill the available space but I want the FlatList items to grow when there is more space available to fill.

This was simple to do using ScrollView (simplified pseudocode):

<ScrollView
  contentContainerStyle={{
    display: "flex",
    flexGrow: 1,
  }}
>
  <Item key={1} style={{ flexGrow: 1 }} />
  <Item key={2} style={{ flexGrow: 1 }} />
</ScrollView>

However it doesn't work for FlatList (simplified pseudocode):

<FlatList
  contentContainerStyle={{
    display: "flex",
    flexGrow: 1,
  }}
  renderItem={({ index }) => <Item key={index} style={{ flexGrow: 1 }} />}
/>

I've created an Expo Snack showing both the ScrollView successfully growing the elements and the FlatList failing to do so.

There seems to be a lot of discussion online about making the parent FlatList full height, but I've struggled to find anything about making the FlatList items grow to fill the available FlatList height.

I need to use FlatList as I plan to use react-native-draggable-flatlist to implement drag and drop and cannot find an equivalent library that doesn't use FlatList.

A screenshot of the Expo Snack is shown here: a

As seen here, it seems the offending issue in the DOM is the CallRenderer, the VirtualizedList is the right height with the right flex styling, and DayItem is set to grow (and worked fine with ScrollView), but in between there's the CallRenderer which seems to interrupt the flex relationship between the two:

b c d

Any help is much appreciated.

React Native version:

System:
    OS: macOS 11.1
    CPU: (8) x64 Intel(R) Core(TM) i7-4770HQ CPU @ 2.20GHz
    Memory: 38.94 MB / 16.00 GB
    Shell: 3.2.57 - /bin/bash
  Binaries:
    Node: 12.18.3 - ~/.nvm/versions/node/v12.18.3/bin/node
    Yarn: 1.22.10 - ~/.nvm/versions/node/v12.18.3/bin/yarn
    npm: 6.14.8 - ~/.nvm/versions/node/v12.18.3/bin/npm
    Watchman: 4.9.0 - /usr/local/bin/watchman
  Managers:
    CocoaPods: Not Found
  SDKs:
    iOS SDK:
      Platforms: iOS 14.4, DriverKit 20.2, macOS 11.1, tvOS 14.3, watchOS 7.2
    Android SDK: Not Found
  IDEs:
    Android Studio: Not Found
    Xcode: 12.4/12D4e - /usr/bin/xcodebuild
  Languages:
    Java: 1.8.0_60 - /usr/bin/javac
    Python: 2.7.16 - /usr/bin/python
  npmPackages:
    @react-native-community/cli: Not Found
    react: 16.13.1 => 16.13.1
    react-native: https://github.com/expo/react-native/archive/sdk-40.0.1.tar.gz => 0.63.2
    react-native-macos: Not Found
  npmGlobalPackages:
    *react-native*: Not Found

Steps To Reproduce

Provide a detailed list of steps that reproduce the issue.

  1. Open snack below and see issue reproduced.

Expected Results

Flexed FlatList to also grow in the same way that ScrollView does, or to provide some way of enabling that same behaviour.

Snack, code example, screenshot, or link to a repository:

https://snack.expo.io/@fredrivett/flex-flatlist-items-to-fill-height-not-working

fredrivett avatar Apr 10 '21 11:04 fredrivett

Try using it like this <FlatList ref={flatListRef} contentContainerStyle={{minHeight: 100, borderWidth: 2}} <--------- data={data || []}

UdjinStolboviy avatar Aug 01 '23 09:08 UdjinStolboviy

Try using it like this <FlatList ref={flatListRef} contentContainerStyle={{minHeight: 100, borderWidth: 2}} <--------- data={data || []}

This is not a solution. This will just add a height to the container of all items not the individual container of each item.

iamrohitagg avatar Oct 18 '23 09:10 iamrohitagg

you can use "CellRenderComponent":

import React from "react";
import {
  SafeAreaView,
  View,
  FlatList,
  StyleSheet,
  Text,
  StatusBar,
} from "react-native";

const DATA = [
  {
    id: "bd7acbea-c1b1-46c2-aed5-3ad53abb28ba",
    title: "First Item",
  },
  {
    id: "3ac68afc-c605-48d3-a4f8-fbd91aa97f63",
    title: "Second Item",
  },
  {
    id: "58694a0f-3da1-471f-bd96-145571e29d72",
    title: "Third Item",
  },
];

const Item = ({ title }) => (
  <View style={styles.item}>
    <Text style={styles.title}>{title}</Text>
  </View>
);

const App = () => {
  return (
    <SafeAreaView style={styles.container}>
      <FlatList
        contentContainerStyle={{ flexGrow: 1 }}
        data={DATA}
        renderItem={({ item }) => <Item title={item.title} />}
        keyExtractor={(item) => item.id}
        CellRendererComponent={({ children, style, style, onLayout, onFocusCapture}) => (
          <View style={[style, {flex: 1}]} children={children}/>
        )}
      />
    </SafeAreaView>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    marginTop: StatusBar.currentHeight || 0,
  },
  item: {
    flex: 1,
    backgroundColor: "#f9c2ff",
    padding: 20,
    marginVertical: 8,
    marginHorizontal: 16,
  },
  title: {
    fontSize: 32,
  },
});

export default App;

mir4n avatar Nov 01 '23 20:11 mir4n

This issue is stale because it has been open 180 days with no activity. Remove stale label or comment or this will be closed in 7 days.

github-actions[bot] avatar May 01 '24 05:05 github-actions[bot]

you can use "CellRenderComponent":

import React from "react";
import {
  SafeAreaView,
  View,
  FlatList,
  StyleSheet,
  Text,
  StatusBar,
} from "react-native";

const DATA = [
  {
    id: "bd7acbea-c1b1-46c2-aed5-3ad53abb28ba",
    title: "First Item",
  },
  {
    id: "3ac68afc-c605-48d3-a4f8-fbd91aa97f63",
    title: "Second Item",
  },
  {
    id: "58694a0f-3da1-471f-bd96-145571e29d72",
    title: "Third Item",
  },
];

const Item = ({ title }) => (
  <View style={styles.item}>
    <Text style={styles.title}>{title}</Text>
  </View>
);

const App = () => {
  return (
    <SafeAreaView style={styles.container}>
      <FlatList
        contentContainerStyle={{ flexGrow: 1 }}
        data={DATA}
        renderItem={({ item }) => <Item title={item.title} />}
        keyExtractor={(item) => item.id}
        CellRendererComponent={({ children, style, style, onLayout, onFocusCapture}) => (
          <View style={[style, {flex: 1}]} children={children}/>
        )}
      />
    </SafeAreaView>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    marginTop: StatusBar.currentHeight || 0,
  },
  item: {
    flex: 1,
    backgroundColor: "#f9c2ff",
    padding: 20,
    marginVertical: 8,
    marginHorizontal: 16,
  },
  title: {
    fontSize: 32,
  },
});

export default App;

I can confirm this is working

suryafaze avatar May 06 '24 11:05 suryafaze