除非initialNumToRender大于总长度,否则FlatList scrollToEnd不起作用?

时间:2018-06-26 13:48:27

标签: javascript reactjs react-native ecmascript-6

不确定我是否在这里遗漏了一些东西,还是应该在RN存储库中打开此问题。

我有FlatList张用户照片,并且在我的应用中具有共享接收设置。当用户将新照片共享到我的应用中时,该照片将添加到列表的底部,并且我想滚动到末尾以显示新添加的内容。

但是,看来我的scrollToEnd通话在FlatList计算完所有子项之前就结束了。本质上,当调用scrollToEnd 时,FlatList似乎在渲染的一半左右,自动滚动最终将您扔到列表的一半左右,而不是全部下来。

顺便说一下,我要处理的列表的长度都在100个项目以下,大多数长度在20个项目以下。

不幸的是,这些列表中的内容大小确实不同,因此getItemLayout不是一个选择。

这就是我在做什么:

平面列表:

<FlatList
  ref={x => this.flatlist = x}
  initialNumToRender={20}
  scrollEventThrottle={1}
  onLayout={(e) => {
    const { height } = e.nativeEvent.layout
    if (height > (images.length * QUEUE_ITEM_HEIGHT) + QUEUE_PADDING_BOTTOM + 200) {
      ui.setAnimatable('queueHelperUI', 'visible', true)
    }
    ui.setDimension('queueLayoutHeight', height)
  }}
  onContentSizeChange={(width, height) => {
    if (height - QUEUE_PADDING_BOTTOM > ui.dimensions.queueLayoutHeight) {
      ui.setAnimatable('queueHelperUI', 'visible', false)
    } else if (!ui.animatables.queueHelperUI.visible) {
      ui.setAnimatable('queueHelperUI', 'visible', true)
    }
  }}
  onScroll={(e) => {
    const { layoutMeasurement, contentOffset, contentSize } = e.nativeEvent
    const atBottom = layoutMeasurement.height + contentOffset.y >=
      (contentSize.height - (QUEUE_PADDING_BOTTOM - 100))
    if (atBottom) {
      ui.setAnimatable('queueHelperUI', 'visible', true)
    } else if (ui.animatables.queueHelperUI.visible) {
      ui.setAnimatable('queueHelperUI', 'visible', false)
    }
  }}
  refreshControl={(
    <RefreshControl
      refreshing={queue.refreshing}
      onRefresh={this.handleRefresh}
      tintColor={whiteSecondary}
    />
  )}
  contentContainerStyle={styles.flatlist}
  data={queueItems}
  renderItem={({ item }) => {
    if (item.key === 'cart-ui') {
        return <CartNotification key={item.key} />
    } else if (item.key === 'helper-ui') {
      return (
        <HelperUI
          key={item.key}
          belowLimit={images.length < 5}
          visible={queueHelperUIVisible}
        />
      )
    }
    return (
      <QueueItem
        {...item}
        deleteImage={queue.deleteImage}
        selectImage={queue.selectImage}
        deselectImage={queue.deselectImage}
        updateImageTransformation={queue.updateImageTransformation}
        selectionActionsAllowed={queue.selectionActionsAllowed}
        key={item.key}
      />
    )
  }}
/>

componentDidUpdate:

componentDidUpdate() {
  /* Upload images automatically */
  const { queue } = this.props
  const { didScrollToBottom } = this.state

  if (queue.imagesToUpload.length > 0 && !queue.currentlyUploading) {
    queue.uploadImage()

    /* Scroll to bottom when new items are added */
    if (!didScrollToBottom) {
      const queueLength = queue.data.images.length
      const screenHeight = Dimensions.get('window').height
      if ((queueLength * QUEUE_ITEM_HEIGHT) + 100 >= screenHeight && this.flatlist) {
        this.flatlist.scrollToEnd()
      }
      this.setState({ didScrollToBottom: true }) // eslint-disable-line
    }
  } else if (queue.imagesToUpload.length === 0 && didScrollToBottom) {
    this.setState({ didScrollToBottom: false }) // eslint-disable-line
  }
}

我要使它完全起作用的唯一方法是将initialNumToRender设置为大于我的总长度的数字-这样就违背了FlatList的目的。

这是如何实现的?我如何等待FlatList完成其子级的计算?

0 个答案:

没有答案