51

I have a horizontal flat list where each item is width:300 All I am trying to do is to get index of currently visible item.

<FlatList 
            onScroll={(e) => this.handleScroll(e)} 
            horizontal={true}
            data={this.state.data}
            renderItem...

Tried this:

handleScroll(event) {
    let index = Math.ceil(
      event.nativeEvent.contentOffset.x / 300
    );

And something like this:

handleScroll(event) {
  let contentOffset = event.nativeEvent.contentOffset;
  let index = Math.floor(contentOffset.x / 300);

but nothing is accurate I always get one index up or one index down.
What am I doing wrong and how to get correct current index in flat list?

For example I get to list item that is 8th in a list but I get index 9 or 10.
enter image description here

4

6 回答 6

83

升级版。感谢@ch271828n 指出不应更新 onViewableItemsChanged

您可以使用 FlatListonViewableItemsChanged道具来获得您想要的东西。

class Test extends React.Component {
  onViewableItemsChanged = ({ viewableItems, changed }) => {
    console.log("Visible items are", viewableItems);
    console.log("Changed in this iteration", changed);
  }

  render () => {
    return (
      <FlatList
        onViewableItemsChanged={this.onViewableItemsChanged }
        viewabilityConfig={{
          itemVisiblePercentThreshold: 50
        }}
      />
    )
  }
}

viewabilityConfig可以通过可见性设置帮助您制作任何您想要的东西。在代码示例50中,如果该项目可见超过 50%,则该项目被视为可见。

配置结构可以在这里找到

于 2017-08-24T19:32:19.573 回答
23

与@fzyzcjy 和@Roman 的答案有关。在反应中,您可以使用 16.8+useCallback来处理changing onViewableItemsChanged on the fly is not supported错误。

    function MyComponent(props) {
        const _onViewableItemsChanged = useCallback(({ viewableItems, changed }) => {
            console.log("Visible items are", viewableItems);
            console.log("Changed in this iteration", changed);
        }, []);
    
        const _viewabilityConfig = {
            itemVisiblePercentThreshold: 50
        }
    
        return <FlatList
                onViewableItemsChanged={_onViewableItemsChanged}
                viewabilityConfig={_viewabilityConfig}
                {...props}
            />;
    }
于 2019-08-13T01:08:30.940 回答
16

非常感谢投票最多的答案:) 但是,当我尝试它时它不起作用,引发了一个错误,说changing onViewableItemsChanged on the fly is not supported. 经过一番搜索,我在这里找到了解决方案。这是可以无错误运行的完整代码。关键是这两个配置应该作为类属性而不是放在 render() 函数中。

class MyComponent extends Component {  
  _onViewableItemsChanged = ({ viewableItems, changed }) => {
    console.log("Visible items are", viewableItems);
    console.log("Changed in this iteration", changed);
  };

  _viewabilityConfig = {
    itemVisiblePercentThreshold: 50
  };

  render() {
    return (
        <FlatList
          onViewableItemsChanged={this._onViewableItemsChanged}
          viewabilityConfig={this._viewabilityConfig}
          {...this.props}
        />
      </View>
    );
  }
}
于 2018-08-04T07:16:39.257 回答
10
this.handleScroll = (event) => {
  let yOffset = event.nativeEvent.contentOffset.y
  let contentHeight = event.nativeEvent.contentSize.height
  let value = yOffset / contentHeight
}

<FlatList onScroll={this.handleScroll} />

获取舍入值以计算页码/索引。

于 2018-01-12T07:48:55.007 回答
6

在你的情况下,我猜你可能会忽略paddingormargin的项目。contentOffsetXorcontentOffsetY应该是firstViewableItemIndex* ( + itemWidth) item padding or margin

在此处输入图像描述

作为其他答案,onViewableItemsChanged将是满足您要求的更好选择。我写了一篇关于如何使用它以及如何实现它的文章。 https://suelan.github.io/2020/01/21/onViewableItemsChanged/

于 2020-02-14T16:08:19.437 回答
1

有点晚了,但对我来说,功能组件有所不同......

如果您使用的是功能组件,请执行以下操作:

  const onScroll = useCallback((event: NativeSyntheticEvent<NativeScrollEvent>) => {
    const slideSize = event.nativeEvent.layoutMeasurement.width;
    const index = event.nativeEvent.contentOffset.x / slideSize;
    const roundIndex = Math.round(index);
    console.log("roundIndex:", roundIndex);
  }, []);

然后在你的 FlatList

<FlatList
      data={[2, 3]}
      horizontal={true}
      pagingEnabled={true}
      style={{ flex: 1 }}
      showsHorizontalScrollIndicator={false}
      renderItem={renderItem}
      onScroll={onScroll}
    />
于 2021-10-21T06:38:44.827 回答