React native 检测滚动视图已到达末尾

React native 检测滚动视图已到达末尾,react-native,react-native-scrollview,React Native,React Native Scrollview,我有一个文本,在滚动视图中有长文本,我想检测用户何时滚动到文本的末尾,以便启用按钮 我一直在从onScroll事件调试事件对象,但似乎没有任何值可以使用。我是这样做的: import React from 'react'; import {ScrollView, Text} from 'react-native'; const isCloseToBottom = ({layoutMeasurement, contentOffset, contentSize}) => { const

我有一个
文本
,在
滚动视图
中有长文本,我想检测用户何时滚动到文本的末尾,以便启用按钮

我一直在从
onScroll
事件调试事件对象,但似乎没有任何值可以使用。

我是这样做的:

import React from 'react';
import {ScrollView, Text} from 'react-native';

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

const MyCoolScrollViewComponent = ({enableSomeButton}) => (
  <ScrollView
    onScroll={({nativeEvent}) => {
      if (isCloseToBottom(nativeEvent)) {
        enableSomeButton();
      }
    }}
    scrollEventThrottle={400}
  >
    <Text>Here is very long lorem ipsum or something...</Text>
  </ScrollView>
);

export default MyCoolScrollViewComponent;
从“React”导入React;
从“react native”导入{ScrollView,Text};
const isCloseToBottom=({layoutMeasurement,contentOffset,contentSize})=>{
常数paddingToBottom=20;
返回layoutMeasurement.height+contentOffset.y>=
contentSize.height-paddingToBottom;
};
const MyCoolScrollViewComponent=({enableSomeButton})=>(
{
如果(isCloseToBottom(nativeEvent)){
enableSomeButton();
}
}}
scrollEventThrottle={400}
>
这是很长的lorem ipsum什么的。。。
);
导出默认MyColScrollViewComponent;

我想添加
paddingToBottom
,因为通常不需要将ScrollView滚动到底部直到最后一个像素。但是,如果您希望将paddingToBottom设置为零。

另一种解决方案可以是使用
ListView
和一行(您的文本),该行具有
onEndReached
方法。请参阅文档

{
让paddingToBottom=10;
paddingToBottom+=e.nativeEvent.layoutMeasurement.height;
如果(e.nativeEvent.contentOffset.y>=e.nativeEvent.contentSize.height-paddingToBottom){
//做点什么。。。
}
}}>...
这样,水平滚动视图(如旋转木马)的反应本机0.44将
isCloseToBottom
功能替换为
isCloseToRight

isCloseToRight = ({ layoutMeasurement, contentOffset, contentSize }) => {
    const paddingToRight = 20;
    return layoutMeasurement.width + contentOffset.x >= contentSize.width - paddingToRight;
};

作为对Henrik R答案的补充:

如果您需要知道用户在装载时是否已到达内容末尾(如果内容可能太长,也可能不太长,具体取决于设备大小)-以下是我的解决方案:

<ScrollView 
        onLayout={this.onLayoutScrollView}
        onScroll={this.onScroll}>
    <View onLayout={this.onLayoutScrollContent}>
        {/*...*/}
    </View>
</ScrollView>

由于人们在这里提供了帮助,我将添加他们编写的简单代码,以使“到达顶部”和“到达底部”事件成为可能。我还做了一个小说明,使事情变得更简单

{
如果(isCloseToTop(nativeEvent)){
//做点什么
}
如果(isCloseToBottom(nativeEvent)){
//做点什么
}
}}
>
目录
isCloseToBottom({layoutMeasurement,contentOffset,contentSize}){
返回layoutmasurement.height+contentOffset.y>=contentSize.height-20;
}
ifCloseToTop({layoutmasurement,contentOffset,contentSize}){
返回contentOffset.y==0;
}
@Henrik R在右边。 但是你也应该使用Math.ceil()


我使用ScrollView,这对我很有用

以下是我的解决方案:

<ScrollView 
        onLayout={this.onLayoutScrollView}
        onScroll={this.onScroll}>
    <View onLayout={this.onLayoutScrollContent}>
        {/*...*/}
    </View>
</ScrollView>
我将onMoneTumScrollEnd道具传递给scrollView,并在event.nativeEvent的基础上在scrollView中实现了onEndReached功能

 onMomentumScrollEnd={(event) => { 
          if (isCloseToBottom(event.nativeEvent)) {
            LoadMoreRandomData()
          }
         }
       }}

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

})

但这需要使用数据源处理文本的每个段落,并创建一个组件(一个简单的文本就可以了)。这主意不错,但实现起来可能有点复杂。您的
onedreached
为我节省了很多时间。ListView已被弃用。请注意,如果您的内容比容器短,则将始终触发此事件。如果您的paddingToBottom为负数(例如,用于处理overscroll),请确保单独处理此情况(基本上通过
contentOffset.y>-paddingToBottom
(注意产生的双负数))这不会触发我的“始终”
onScroll
仅在用户滚动时调用。在滚动结束时,它工作正常,但当我从最后一个结束点向上滚动时,它被调用。那么,当向上滚动时,有什么解决方案可以阻止这个问题吗?为什么要使用Ceil?
<ScrollView
onScroll={({nativeEvent})=>{
if(isCloseToTop(nativeEvent)){
    //do something
}
if(isCloseToBottom(nativeEvent)){
   //do something
}
}}
>
...contents
</ScrollView>



isCloseToBottom({layoutMeasurement, contentOffset, contentSize}){
   return layoutMeasurement.height + contentOffset.y >= contentSize.height - 20;
}



ifCloseToTop({layoutMeasurement, contentOffset, contentSize}){
   return contentOffset.y == 0;
}
function handleInfinityScroll(event) {
        let mHeight = event.nativeEvent.layoutMeasurement.height;
        let cSize = event.nativeEvent.contentSize.height;
        let Y = event.nativeEvent.contentOffset.y;

        if(Math.ceil(mHeight + Y) >= cSize) return true;
        return false;
}
 onMomentumScrollEnd={(event) => { 
          if (isCloseToBottom(event.nativeEvent)) {
            LoadMoreRandomData()
          }
         }
       }}

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