如何在RN平面列表中获取当前可见的索引

111*_*110 20 javascript react-native react-native-scrollview react-native-flatlist

我有一个水平的平面列表,其中每个项目是width:300 我想要做的是获取当前可见项目的索引.

<FlatList 
            onScroll={(e) => this.handleScroll(e)} 
            horizontal={true}
            data={this.state.data}
            renderItem...
Run Code Online (Sandbox Code Playgroud)

试过这个:

handleScroll(event) {
    let index = Math.ceil(
      event.nativeEvent.contentOffset.x / 300
    );
Run Code Online (Sandbox Code Playgroud)

这样的事情:

handleScroll(event) {
  let contentOffset = event.nativeEvent.contentOffset;
  let index = Math.floor(contentOffset.x / 300);
Run Code Online (Sandbox Code Playgroud)

但没有什么是准确的我总是得到一个索引或一个索引下来.
我做错了什么以及如何在平面列表中获得正确的当前索引?

例如,我在列表中列出第8项,但我得到索引9或10.
在此输入图像描述

Rom*_*pov 38

UPD.感谢fzyzcjy指出onViewableItemsChanged不应该更新

您可以使用FlatList onViewableItemsChangedprop来获得所需内容.

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
        }}
      />
    )
  }
}
Run Code Online (Sandbox Code Playgroud)

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

配置结构可以在这里找到

  • 在 react native 0.54 中说:**ExceptionsManager.js:65 Invariant Violation: Change onViewableItemsChanged on the fly is not supported** (5认同)

tir*_*ran 15

与@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}
            />;
    }
Run Code Online (Sandbox Code Playgroud)

  • 我可以问为什么吗? (2认同)

fzy*_*cjy 8

非常感谢最投票的答案:)但是,当我尝试它时,它不起作用,并显示了一个错误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>
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

  • 我也遇到了这个问题,但我使用的是功能组件,而不是类。你有什么想法可以帮助我吗? (3认同)
  • 聚会有点晚了,但这里是 Github 上问题的链接,其中一位贡献者提出了功能组件的解决方案。希望它能帮助某人https://github.com/facebook/react-native/issues/30171#issuecomment-711154425 (2认同)

RY_*_*eng 6

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

在此处输入图片说明

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


man*_*urt 6

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

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

  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);
  }, []);
Run Code Online (Sandbox Code Playgroud)

然后在你的 FlatList 上

<FlatList
      data={[2, 3]}
      horizontal={true}
      pagingEnabled={true}
      style={{ flex: 1 }}
      showsHorizontalScrollIndicator={false}
      renderItem={renderItem}
      onScroll={onScroll}
    />
Run Code Online (Sandbox Code Playgroud)


Suj*_*jit 5

this.handleScroll = (event) => {
  let yOffset = event.nativeEvent.contentOffset.y
  let contentHeight = event.nativeEvent.contentSize.height
  let value = yOffset / contentHeight
}

<FlatList onScroll={this.handleScroll} />
Run Code Online (Sandbox Code Playgroud)

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