【问题标题】:FlatList item taking full available height?FlatList 项目占用全部可用高度?
【发布时间】:2020-11-20 18:52:38
【问题描述】:

有没有办法让垂直平面列表项占据全高? 希望使用 flex,而不使用Dimensions API,因为我的平面列表是在堆栈和选项卡导航中呈现的,因此很难获得可用高度,并且如果存在缺口几乎无法预测。

   <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>
    );
  }}
/>

【问题讨论】:

    标签: react-native expo


    【解决方案1】:

    确保主父组件的 flex 值为 1。

    这是一个示例应用的屏幕截图:

    修改后的示例代码:

    这里我将默认高度保持为100,如果项目数量相对较高并且它们的平均高度变得小于100,那么我将项目的高度设置为100或平均高度。

    即如果FlatList 的高度为500 并且有10 项目,那么它们的平均高度将为500/50 = 10,这太小而无法容纳ListItem 的内容,所以我不会将高度设置为10切换到100,相反,如果只有2 项目则500/2= 250,大于默认高度100,所以在这种情况下,我使用平均值,即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;
    
    

    完整的工作示例链接:Expo Snack

    【讨论】:

    • 我需要平面列表中的项目也占据全高,在这种情况下,项目容器将覆盖可用高度(粉红色区域)。如果不手动设置 dp 中的项目高度或屏幕高度百分比,这可能吗?
    【解决方案2】:

    我使用了 https://stackoverflow.com/a/63198139/13551249 中建议的 flatlist 的 onLayout 道具

    基本上它会计算 flatlist 正在使用的空间量,并且该高度可用于设置 flatlist 内项目的高度,因此项目将占据 flatlist 的整个高度。

    【讨论】:

    • 如果FlatList 有200 个项目,而FlatList 的高度为1000px,这些项目之间的高度将如何分配?
    • 在我的用例中,每个项目都将采用 flatlist 全高(在您的示例中为 1000px)。 Flatlist 是可滚动的,所以里面的项目如何变大取决于你。Flatlist 不会将 1000px 的总和分配给每个项目。
    • 不错。我以为你在动态分配高度。谢谢你,我知道了onLayout :D 好问题。
    猜你喜欢
    • 1970-01-01
    • 2021-12-14
    • 1970-01-01
    • 2022-10-04
    • 2020-02-10
    • 2022-01-25
    • 2021-09-04
    • 2020-12-19
    • 2013-06-02
    相关资源
    最近更新 更多