【问题标题】:React Native horizontal FlatList with multiple rows用多行反应原生水平 FlatList
【发布时间】:2017-08-29 12:58:16
【问题描述】:

我正在尝试实现一个有两行的水平滚动列表。使用 FlatList,垂直滚动列表涉及设置numColumns,但没有与水平使用行的等效项。

我成功地使其正确渲染,并且完美无缺。但是,会抛出警告,指出在VirtualizedListFlatList 中不支持设置flexWrap,并使用numColumns。我不能使用 numColumns,因为这不适用于水平列表。

<FlatList
    horizontal={true}
    contentContainerStyle={{
        flexDirection: 'column',
        flexWrap: 'wrap'
    }}
    {...otherProps}
/>

我找到了添加此警告的提交,但找不到其背后的原因。似乎没有任何方法可以在不发出警告的情况下完成这项工作,至少在不完全放弃 FlatList 的情况下。有行的水平列表更合适的解决方案吗?

参考资料:

【问题讨论】:

  • 你有没有为多行的水平 FlatList 找到任何好的解决方案?
  • 期待同样的分辨率
  • 这很棒,谢谢分享!我还向容器(包含 FlatList)添加了一个高度,并且能够以这种方式将其强制为 2 行。

标签: react-native


【解决方案1】:

增强第一个答案,这就是我所做的:

const listData = props.data ?? [];
const numColumns = Math.ceil(listData.length / 2);
        <ScrollView
          horizontal
          showsVerticalScrollIndicator={false}
          showsHorizontalScrollIndicator={false}
          contentContainerStyle={{ paddingVertical: 20 }}>
          <FlatList
            scrollEnabled={false}
            contentContainerStyle={{
              alignSelf: 'flex-start',
            }}
            numColumns={numColumns}
            showsVerticalScrollIndicator={false}
            showsHorizontalScrollIndicator={false}
            data={listData}
            renderItem={renderItem}
          />
        </ScrollView>

【讨论】:

    【解决方案2】:

    请不要使用horizontal={true}。对于这种情况 你应该使用等于数据长度/2的numColumns,并添加一个&lt;ScrollView&gt;标签。强制列数为总数的一半将强制列表换行到下一行。

    <ScrollView>
        <FlatList
            contentContainerStyle={{alignSelf: 'flex-start'}}
            numColumns={Math.ceil(listData.length / 2)}
            showsVerticalScrollIndicator={false}
            showsHorizontalScrollIndicator={false}
            data={listData}
            renderItem={({ item, index }) => {
                //push your code
            }}
        />
    </ScrollView>
    

    更新 1:在 Alex Aung 评论之后编辑 listData.length / 2 -> Math.ceil(listData.length / 2)。谢谢亚历克斯

    【讨论】:

    • numColumns={Math.ceil(featuredCategories.length / 2)}
    • numColumns={listData.length / 2}错误不能当场执行。
    【解决方案3】:

    我用简单的逻辑看看

    <ScrollView
        horizontal
        showsHorizontalScrollIndicator={false}
        contentContainerStyle={{
            justifyContent: 'center',
            paddingHorizontal: 20,
            paddingBottom: 70,
        }}>
        <View>
            <View style={{ flexDirection: 'row', flexWrap: 'wrap' }}>
                {this.state.interest.length
                    ? this.state.interest.map((d, i) => {
                        if (i % 2 == 0) {
                            return null;
                        }
                        return (
                            <Intrest
                                style={{
                                    height: 40,
                                    paddingHorizontal: 20,
                                    alignItems: 'center',
                                    justifyContent: 'center',
                                    borderRadius: 30,
                                    margin: 2.5,
                                }}
                                key={i}
                                data={d}
                                add={data => {
                                    this._handleAddtoSelection(data);
                                }}
                                remove={data => {
                                    this._handleRemoveFromSelection(data);
                                }}
                                active={this._isSelectedTopic(d)}
                            />
                        );
                    })
                    : null}
            </View>
            <View style={{ flexDirection: 'row', flexWrap: 'wrap' }}>
                {this.state.interest.length
                    ? this.state.interest.map((d, i) => {
                        if (i % 2 != 0) {
                            return null;
                        }
                        return (
                            <Intrest
                                style={{
                                    height: 40,
                                    paddingHorizontal: 20,
                                    alignItems: 'center',
                                    justifyContent: 'center',
                                    borderRadius: 30,
                                    margin: 2.5,
                                }}
                                key={i}
                                data={d}
                                add={data => {
                                    this._handleAddtoSelection(data);
                                }}
                                remove={data => {
                                    this._handleRemoveFromSelection(data);
                                }}
                                active={this._isSelectedTopic(d)}
                            />
                        );
                    })
                    : null}
            </View>
        </View>
    </ScrollView>
    

    输出:Output

    【讨论】:

    • 如果我想要 3 行在这我必须改变。你能告诉我这个吗? @ronak
    【解决方案4】:

    我在一个不长的项目列表(几百个)上遇到了同样的问题,我设法通过查看我的列表将它们映射到多个视图来克服它,每个视图一个接一个地有 2 个项目(列使用弹性)

    如果你的列表不太长,你也可以使用ScrollView,它支持flexWrap

    【讨论】:

      【解决方案5】:

      通过一些预处理工作将每个ROWS_COUNT 分割成一列

      const ROWS_COUNT = 5;
      const len = Math.ceil(data.length / ROWS_COUNT );
      const cols = () => {
          let colsArr = Array(len);
          for (let i = 0; i < len; i++) {
              colsArr[i] = 
                  <View style={styles.col}>
                      {Array(ROWS_COUNT ).fill(0).map((_, j) => {
                          let index = i * ROWS_COUNT + j;
                          return (index < data.length) ? <NumSquare key={index} num={index} active={index < 23} color={"#44afff"}/> : <></>
                      })}
                  </View>
                          
          }
          return colsArr;
      }
      const colsArr = cols();
      
      ..................................
      
      <FlatList
          horizontal
          data={colsArr}
          contentContainerStyle={styles.contentContainerStyle}
          showsVerticalScrollIndicator={false}
          showsHorizontalScrollIndicator={false}
          renderItem={({ item, index }) => item}/>
      
      ..................................
      
      const styles = StyleSheet.create({
          col:{
              flexDirection:"column",
          }
      });
      

      结果:

      【讨论】:

        猜你喜欢
        • 2018-07-13
        • 1970-01-01
        • 2019-04-23
        • 1970-01-01
        • 1970-01-01
        • 2018-12-02
        • 2018-04-17
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多