web-dev-qa-db-ja.com

ScrollViewの検出が終了した

Text内に長いテキストを持つScrollViewがあり、ユーザーがボタンを有効にできるようにテキストの最後までスクロールしたことを検出したい。

onScrollイベントからイベントオブジェクトをデバッグしましたが、使用できる値はないようです。

25
Eldelshell

私はこのようにしました:

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;

通常、ScrollViewを最後のピクセルまで下にスクロールする必要はないため、paddingToBottomを追加しました。ただし、必要な場合はpaddingToBottomをゼロに設定します。

64
Henrik R
<... onScroll={(e) => {
        let paddingToBottom = 10;
        paddingToBottom += e.nativeEvent.layoutMeasurement.height;
        if(e.nativeEvent.contentOffset.y >= e.nativeEvent.contentSize.height - paddingToBottom) {
          // make something...
        }
      }}>...

このような反応ネイティブ0.44

12

ここで人々が助けてくれたので、私は彼らが書く簡単なコードを追加して、一番上に到達し、一番下に到達するイベントを作成し、物事をより簡単にするために少し説明しました

Layout and vars values

<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;
}
5
Louay Alosh

別の解決策は、ListViewメソッドを持つ単一行(テキスト)でonEndReachedを使用することです。ドキュメントを参照してください here

4
David

@Henrik Rの権利。ただし、Math.ceil()も使用する必要があります。

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;
}

enter image description here

2
Fuad Cavadov

水平ScrollView(カルーセルなど)の場合、isCloseToBottom関数をisCloseToRightに置き換えます

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

Henrik Rの答えに加えて:

マウント時にユーザーがコンテンツの最後に到達したかどうかを知る必要がある場合(コンテンツがデバイスのサイズに応じて長すぎる場合とそうでない場合)-ここに私の解決策があります:

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

と組み合わせて

onLayout(wrapper, { nativeEvent }) {
    if (wrapper) {
        this.setState({
            wrapperHeight: nativeEvent.layout.height,
        });
    } else {
        this.setState({
            contentHeight: nativeEvent.layout.height,
            isCloseToBottom:
              this.state.wrapperHeight - nativeEvent.layout.height >= 0,
        });
    }
}
1
Malte Peters