React native 反应本机水平滚动视图分页:预览下一页/卡片

React native 反应本机水平滚动视图分页:预览下一页/卡片,react-native,pagination,scrollview,carousel,horizontalscrollview,React Native,Pagination,Scrollview,Carousel,Horizontalscrollview,我想创建一个水平滚动视图,启用分页,但有一个特殊要求:每个页面(或卡片)都是容器宽度的90%。剩下的10%应该是下一页的预览 是否可以使用ScrollView执行此操作?我可以指定分页的宽度而不是容器的宽度吗 (从类似问题中拍摄的图像:)您可以将水平道具传递到滚动视图: 然后可以在内部创建视图以指定宽度要求 <ScrollView ref={(snapScroll) => { this.snapScroll = snapScroll; }} horizontal={tr

我想创建一个水平滚动视图,启用分页,但有一个特殊要求:每个页面(或卡片)都是容器宽度的90%。剩下的10%应该是下一页的预览

是否可以使用ScrollView执行此操作?我可以指定分页的宽度而不是容器的宽度吗


(从类似问题中拍摄的图像:)

您可以将水平道具传递到滚动视图:

然后可以在内部创建视图以指定宽度要求

<ScrollView 
  ref={(snapScroll) => { this.snapScroll = snapScroll; }}
  horizontal={true} 
  decelerationRate={0}
  onResponderRelease={()=>{

   var interval = 300; // WIDTH OF 1 CHILD COMPONENT 

   var snapTo = (this.scrollingRight)? Math.ceil(this.lastx / interval) : 
    Math.floor(this.lastx / interval);
   var scrollTo = snapTo * interval;
   this.snapScroll.scrollTo(0,scrollTo);
  }}
  scrollEventThrottle={32}
  onScroll={(event)=>{
    var nextx = event.nativeEvent.contentOffset.x;
    this.scrollingRight = (nextx > this.lastx);
    this.lastx = nextx;
  }}
  showsHorizontalScrollIndicator={false} 
  style={styles.listViewHorizontal}
  >

  {/* scroll-children here */}

</ScrollView>
{this.snapScroll=snapScroll;}
水平={true}
减速率={0}
onResponderRelease={()=>{
var interval=300;//1个子组件的宽度
var snapTo=(this.scrollingRight)?Math.ceil(this.lastx/interval):
数学层(this.lastx/间隔);
var scrollTo=snapTo*间隔;
this.snapScroll.scrollTo(0,scrollTo);
}}
scrollEventThrottle={32}
onScroll={(事件)=>{
var nextx=event.nativeEvent.contentOffset.x;
this.scrollingRight=(nextx>this.lastx);
this.lastx=nextx;
}}
showshorizontalscrolindicator={false}
style={styles.listViewHorizontal}
>
{/*在此处滚动子项*/}

您可以查看ScrollView的
contentOffset
scrollTo
属性。从逻辑上讲,只要页面发生更改(主要是移动到下一页),您就可以根据需要提供10%左右的额外偏移量,以便scrollview中的下一项可见


希望这有帮助,如果你需要任何额外的细节,请告诉我

我花了很多时间来解决这个问题,直到我弄明白为止,所以如果它对某人有帮助,这里是我的解决方案

问题是所有这些都是必需的,分页应该关闭

horizontal={true}
decelerationRate={0}
snapToInterval={width - 60}
snapToAlignment={"center"}

您完全可以使用
ScrollView
或更好的
FlatList
来实现这一点。然而,真正棘手的部分是捕捉效果。您可以使用props
snapToInterval
snapToAlignment
来实现它(请参阅);不幸的是,这些只是iOS

我和一位同事创建了一个插件来满足这个特殊的需求。我们最终开放了它的来源,所以您可以尝试:

该插件现在构建在
FlatList
(版本>=3.0.0)之上,非常适合处理大量项目。它为iOS和Android提供了预览(您追求的效果)、抓拍效果、视差图像、RTL支持,等等

您可以查看一下,以了解使用它可以实现什么。不要犹豫,分享你的经验与插件,因为我们总是试图改善它


编辑:已在版本
3.6.0
中引入(一个具有一叠卡片效果,另一个具有类似火绒的效果)。享受吧


您可以使用内置的
滚动视图组件构建水平滚动。差不多

<View style = { style.`custom-style` }>
   <ScrollView horizontal = { true } showsHorizontalScrollIndicator = { false 
   }>
    `...YOUR-CHILDREN-COMPONENTS`
   </ScrollView>
</View>

`…您的子组件`

如果您想为flex box“
justifyContent
添加样式,请使用
contentContainerStyle={{justifyContent:
your choice value
}
当然,如果您愿意,您可以从
样式表
中引用该属性,例如
ContentContainerStyles={styles.contentContainer}
#干杯

在滚动视图中使用disableIntervalMomentum={true}。这将只允许用户一次水平滚动一页。检查官方文件


下面是底部的简单滚动视图分页示例:

<ScrollView
......
onMomentumScrollEnd={event => {
   if (isScrollviewCloseToBottom(event.nativeEvent)) {
      this.loadMoreData();
   }
}}
</ScrollView>

.....
....

function isScrollviewCloseToBottom({
  layoutMeasurement,
  contentOffset,
  contentSize,
}) {
  const paddingToBottom = 20;
  return (
    layoutMeasurement.height + contentOffset.y >=
    contentSize.height - paddingToBottom
  );
}

......
....

希望这会有帮助

我在ScrollView中将
horizontal={true}paginEnabled={true}
作为道具。但是“滚动时滚动视图停止在滚动视图大小的倍数上”也可以查看此问题以获得帮助@AlfredAlfizoMosima Sure;-)一个简单的例子。尝试实现类似的功能,但使用recyclerlistview。。FlatList对我来说有太多问题了你们是很棒的家伙。。感谢这个伟大的组件。我被flatlist困住了,它试图获取一些动画相关内容的当前活动项索引。我试了一整天,但对于大数据集来说失败了。Snap Carousal提供了完美的结果。再次感谢。
<ScrollView
......
onMomentumScrollEnd={event => {
   if (isScrollviewCloseToBottom(event.nativeEvent)) {
      this.loadMoreData();
   }
}}
</ScrollView>

.....
....

function isScrollviewCloseToBottom({
  layoutMeasurement,
  contentOffset,
  contentSize,
}) {
  const paddingToBottom = 20;
  return (
    layoutMeasurement.height + contentOffset.y >=
    contentSize.height - paddingToBottom
  );
}

......
....
function isScrollviewCloseToRight({
  layoutMeasurement,
  contentOffset,
  contentSize,
}) {
  const paddingToRight = 10;
  return (
    layoutMeasurement.width + contentOffset.x >=
    contentSize.width - paddingToRight
  );
}