如何使Flex React Native FlatList的子项充满整个高度?

9

我正在使用React Native中的FlatList来呈现一堆叠在一起的项目。

这很好用,我已经成功地使FlatList本身扩展其高度以填充可用空间,但是当有更多的空间时,我希望FlatList的项目也能够增长。

使用ScrollView这个简化的伪代码实现起来很简单:

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

然而,它对于 FlatList (简化伪代码)无效:
<FlatList
  contentContainerStyle={{
    display: "flex",
    flexGrow: 1,
  }}
  renderItem={({ index }) => <Item key={index} style={{ flexGrow: 1 }} />}
/>

我创建了一个Expo Snack,展示了ScrollView成功地使元素增长,而FlatList则无法实现。

关于使父级FlatList充满整个高度的讨论似乎很多,但我很难找到有关使FlatList 增长以填充可用FlatList高度的任何信息。

我需要使用FlatList,因为我计划使用react-native-draggable-flatlist来实现拖放,并且找不到不使用FlatList的等效库。

这里展示了Expo Snack的截图: ScrollView项目可以增长以填充可用高度,但FlatList项目无法做到相同 如图所示,DOM中的问题似乎是CallRendererVirtualizedList具有正确的高度和正确的flex样式,DayItem被设置为增长(并且在使用ScrollView时运行正常),但在它们之间存在CallRenderer,它似乎打断了两者之间的flex关系:

Screenshot inspecting VirtualizedList Screenshot inspecting CallRenderer Screenshot inspecting FlatList child item

任何帮助都非常感激。

如果您将minHeight: screen设置为flatlist,可能有助于解决这个问题。 - Craques
@Craques FlatList 本身已经在可用高度上增长,只是其中的项目不会增长(尽管父级为 flex,子级为 flexGrow: 1,似乎 CallRenderer 破坏了 flex 设置)。 - fredrivett
3个回答

4

解决方法是监听FlatList的onLayout事件,将计算出的高度保存在一个状态中,然后将每个子元素的高度设置为flatlist高度除以数据长度。


嗯,这可能可以用 minHeight 作为备选方案,希望只使用 CSS 来解决它,但会记住的,谢谢! - fredrivett

1
我发现实现这个的最佳方法是将屏幕高度或者在你的例子中,flatlist本身的高度除以列表项数(或者你想一次填充屏幕的项目数),并将其设置为renderItem的高度。
 const items = [ { text: "First item" }, { text: "Second item"} ];

 // height given to flatlist
 const FLATLIST_HEIGHT= 200;

 // or number of Items I want to fill screen
 const ITEMS_COUNT = items.length;

 const renderItem = ({ item, index, drag, isActive }) => {
    return (
      <View
        style={{
          borderWidth: 2,
          height: Math.floor(FLATLIST_HEIGHT/ITEMS_COUNT) - 2,
          // minus 2 to compensate for borderWidth
        }}
      >
        <Text>{item.text}</Text>
      </View>
    );
  };

...

 const myFlatList = (
    <FlatList
      data={items}
      renderItem={renderItem}
      keyExtractor={item => item.id}
      contentContainerStyle={{
        height: FLATLIST_HEIGHT,
      }}
    />
  );

在没有填满屏幕的平面列表的情况下,只需设置窗口高度的值:

import {..., Dimensions} from 'react-native';

...
const HEIGHT = Dimensions.get('window').height;

const renderItem = ({ item, index, drag, isActive }) => {
    return (
      <View
        style={{
          borderWidth: 2,
          height: Math.floor(HEIGHT/ITEMS_COUNT) - 2,
          // minus 2 to compensate for borderWidth
        }}
      >
        <Text>{item.text}</Text>
      </View>
    );
  };

0

每个项目flex: 1,而不是整个 flatlist


谢谢你的回复Ehsan,但这些项目已经有了flexGrow: 1,设置简写的flex: 1只会设置flexShrinkflexBasis,在尝试之后并没有什么区别。可以在这里看到代码:https://snack.expo.io/@fredrivett/flex-flatlist-items-to-fill-height-not-working - fredrivett
似乎有些奇怪?你介意检查一下FlatList的内部细节,以便了解它的内部工作方式。 - TheEhsanSarshar
我认为是因为性能的原因。FlatList 总是为每个项目分配一个已计算的高度。 - TheEhsanSarshar
一个解决方法是将FlatList的高度除以项目数量。 - TheEhsanSarshar
或者您可以在 GitHub 上开一个问题。 - TheEhsanSarshar
是的,我同意这可能是出于性能设计考虑,但是在我的研究中还没有看到任何提到这一点的内容。我可能需要在 GitHub 上开一个问题,但我认为这更像是一个问题而不是一个错误/限制。我也会在那里问问,谢谢! - fredrivett

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接