在numColumns中包含ListHeaderComponent - React-Native

时间:2018-02-14 17:42:13

标签: react-native react-native-flatlist

有谁知道如何在列中包含平面列表的标题? 例如,在下图中,我希望“Design”在同一行中跟随“New +”。

Example Screenshot

这是我在渲染中的代码:

paste(do.call(paste, c(strsplit(c(x, y), ","), sep = ", ")), collapse = "\n")
# [1] "col1, col2\n1, a\n2, b\n3, c\n4, d"

library(tidyverse)
read_csv(paste(do.call(paste, c(strsplit(c(x, y), ","), sep = ", ")), collapse = "\n"))
# # A tibble: 4 x 2
#    col1 col2 
#   <int> <chr>
# 1     1 a    
# 2     2 b    
# 3     3 c    
# 4     4 d  

和_renderGoal:

<FlatList
  data={goalItems}
  extraData={this.props}
  renderItem={this._renderGoal}
  ListHeaderComponent={this._renderGoalHeader}
  keyExtractor={item => item.goal_id}
  showsVerticalScrollIndicator={false}
  numColumns={2}
/>

并在_renderGoalHeader中:

_renderGoal = ({ item }) => (
  <TouchableOpacity 
    onPress={() => this.openOptions(item)} 
    style={{ padding: 10 }}>
    <Bubble>
      <Text style={[styles.normalText]}>{item.name}</Text>
      <View style={{ alignItems: 'center' }}>
        <Text>{formatSeconds(item.total_time)}</Text>
      </View>
    </Bubble>
  </TouchableOpacity>
);

提前致谢。

作为临时修复,我从flatList中删除了numColums并添加了以下内容:

_renderGoalHeader = () => (
  <TouchableOpacity 
    onPress={() => this.openAddGoal()} 
    style={{ padding: 10 }}>
    <Bubble style={[styles.newGoal]}>
      <Text style={[styles.touchableText]}>New +</Text>
    </Bubble>
  </TouchableOpacity>
)

2 个答案:

答案 0 :(得分:0)

我希望在这里被证明是错误的,但据我所知,使用numColumns无法做到这一点。我将在最后列出一个解决方法,但首先是推理:

<强>解释

我遇到了同样的问题,但是使用页脚并执行了一个代码,潜入React Native源代码,看看发生了什么。我做的第一件事是使用检查器,我注意到FlatList的页眉和页脚包含在View中,而每行列都包含在CellRenderer > View中。这是FlatList未考虑numColumns中页眉和页脚的第一个线索。这是有问题的,因为FlatList does not support masonry type layouts。这暗示了这样一个事实:关于它们如何处理渲染行有很多假设 - 也就是说,项目被分成要呈现的行。

通过这些线索,我进入了源代码,发现FlatList将自己的custom renderItem传递给VirtualizedList。同时,ListHeaderComponentListFooterComponent按原样传递。它们从未在FlatList中使用过。这不是一个好兆头,因为您会看到前面提到的_renderItem处理将项目分组到要使用flexDirection: 'row'进行渲染的列以及使用columnWrapperStyle传递的任何内容。

但也许VirtualizedList非常聪明,可以将页眉和页脚合并到data中,并传递到renderItem

可悲的是,事实并非如此。如果您按照VirtualizedList中的代码进行操作,您最终会看到所有逻辑都在render()中播放,其中:

  1. 创建cells array
  2. 首先拥有header pushed into it
  3. 后跟所有data pushed into it及其_pushCells helper method
    • 这是CellRenderer出现的地方;
    • 因此,为什么页眉和页脚不被此包裹,而行是。
    • 这也是FlatLists _renderItem is used解释为什么numColumns包含CellRenderer个项目的原因。
  4. 然后以与标题相同的方式完成footer being pushed
  5. 这个cells React组件数组最终会cloned,这有助于保持滚动位置。
  6. 最后rendered
  7. 对于此实现,您将始终获得一个固定的CellRenderer组件,该组件会阻止页眉和页脚作为numColumns的一部分包含在内。

    解决方法(不推荐)

    如果您在FlatList发布之前使用过React Native,您就会知道一个旧的解决方法是对您的维度非常小心并使用flexWrap: 'wrap'。如果你使用这种处理列的方法,它实际上是documented within the source code as it will spit out a warning。请注意,建议执行 NOT (我相信性能和滚动位置可能是使用此方法的一些原因)。

    如果您愿意这样做,请将这些样式添加到contentContainerStyle

    flexDirection: 'row',
    flexWrap: 'wrap',
    // You'll probably also want this for handling empty cells at the end:
    justifyContent: 'flex-start',
    

    并删除numColumns道具。然后确保手动调整组件尺寸,以获得所需的正确列式样布局。这应该允许您的页眉和页脚作为列的一部分呈现。

答案 1 :(得分:-1)

如果你想用numOfColumns做,而不是使用flexDirection:标题组件中的'row'

_renderGoalHeader = () => (
 return(
  <View style={{flexDirection:'row'}}>
  <TouchableOpacity 
    onPress={() => this.openAddGoal()} 
    style={{ flex:1, padding: 10, }}>
    <Bubble style={[styles.newGoal]}>
      <Text style={[styles.touchableText]}>New +</Text>
    </Bubble>
  </TouchableOpacity>
 <View>
 <View style={{flex:1}}/> //this view is just to cover half width
 );
)