React native 平面列表可见位置

React native 平面列表可见位置,react-native,React Native,我正在尝试呈现一个弯曲的垂直列表,如以下iOS组件: 该组件(用Obj-c编写)在布局可见单元时迭代这些单元,并使用asin设置框架(即缩进) 我知道在React Native中,我可以在renderItem回调中设置leftMargin样式,但我不知道如何获取项目的屏幕索引-我所拥有的只是源数据的索引。而且,在这一点上,我认为我无法获得绝对位置 有什么想法吗 React native的FlatList组件有一个名为。你可以用这个道具在屏幕上得到组件的位置 仅限布局 在装载和布局更改时调用: {

我正在尝试呈现一个弯曲的垂直列表,如以下iOS组件:

该组件(用Obj-c编写)在布局可见单元时迭代这些单元,并使用asin设置框架(即缩进)

我知道在React Native中,我可以在renderItem回调中设置leftMargin样式,但我不知道如何获取项目的屏幕索引-我所拥有的只是源数据的索引。而且,在这一点上,我认为我无法获得绝对位置


有什么想法吗

React native的
FlatList
组件有一个名为。你可以用这个道具在屏幕上得到组件的位置

仅限布局

在装载和布局更改时调用:

{nativeEvent: { layout: {x, y, width, height}}}
计算布局后立即触发此事件, 但新的布局可能还没有反映在当时的屏幕上 收到事件,尤其是在布局动画处于活动状态时 进步


您正在寻找的功能是 对可视项目进行更改。 您可以将其与可视性配置一起使用,该配置为我们提供 最小查看时间、查看区域覆盖率百分比阈值、等待交互 可以相应地进行设置

const VIEWABILITY_CONFIG = {
     minimumViewTime: 3000,
      viewAreaCoveragePercentThreshold: 100,
    waitForInteraction: true,
};


 _onViewableItemsChanged = (info: {
  changed: Array<{
    key: string,
    isViewable: boolean,
    item: any,
    index: ?number,
    section?: any,
     }>
    }
 ){
  //here you can have the index which is visible to you
  }

<FlatList
  renderItem={this.renderItem}
  data={this.state.data}
  onViewableItemsChanged={this._onViewableItemsChanged}
  viewabilityConfig={VIEWABILITY_CONFIG}
 />
const可视性\u配置={
最小查看时间:3000,
ViewArea覆盖率百分比阈值:100,
waitForInteraction:是的,
};
_onViewableItemsChanged=(信息:{
更改:数组
}
){
//在这里,您可以看到索引
}

谢谢你的两个答案

我最后做的是使用列表的滚动偏移量导出可见项。这很简单,因为列表项都具有相同的高度

我在onScroll处理程序中执行此操作,并在此时计算每个项目的水平偏移量(并使用leftMargin/rightMargin来渲染)。它并不完美,但它确实给了我一个椭圆形的列表

_handleScroll = (event) => {
  const topItemIndex = Math.floor(event.nativeEvent.contentOffset.y / LIST_ITEM_HEIGHT);
  const topItemSpare  = LIST_ITEM_HEIGHT-(event.nativeEvent.contentOffset.y % LIST_ITEM_HEIGHT);

  const positionFromEllipseTop = (forIndex-topItemIndex)*LIST_ITEM_HEIGHT+topItemSpare;
  const positionFromOrigin = Math.floor(Math.abs(yRadius - positionFromEllipseTop));

  const angle   = Math.asin(positionFromOrigin / yRadius);

  if (orientation === 'Left') {
    marginLeft  = 0;
    marginRight = ((xRadius * Math.cos(angle)))-LIST_ITEM_HEIGHT;
    alignSelf = 'flex-end';
  }
  else if (orientation === 'Right') {
    marginLeft  = (xRadius * Math.cos(angle))-LIST_ITEM_HEIGHT;
    marginRight = 0;
    alignSelf = 'flex-start';
  }
}