Detect ScrollView has reached the end

前端 未结 7 1068
栀梦
栀梦 2020-12-23 21:32

I have a Text with long text inside a ScrollView and I want to detect when the user has scrolled to the end of the text so I can enable a button.

相关标签:
7条回答
  • 2020-12-23 21:46

    As people helped here I will add the simple code they write to make reached to top and reached to bottom event and I did a little illustration to make things simpler

    <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;
    }
    
    0 讨论(0)
  • 2020-12-23 21:48

    Another solution could be to use a ListView with a single row (your text) which has onEndReached method. See the documentation here

    0 讨论(0)
  • 2020-12-23 21:54
    <... onScroll={(e) => {
            let paddingToBottom = 10;
            paddingToBottom += e.nativeEvent.layoutMeasurement.height;
            if(e.nativeEvent.contentOffset.y >= e.nativeEvent.contentSize.height - paddingToBottom) {
              // make something...
            }
          }}>...
    

    like this react-native 0.44

    0 讨论(0)
  • 2020-12-23 21:54

    As an addition to the answer of Henrik R:

    If you need to know wether the user has reached the end of the content at mount time (if the content may or may not be too long, depending on device size) - here is my solution:

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

    in combination with

    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,
            });
        }
    }
    
    0 讨论(0)
  • 2020-12-23 21:56

    I did it like this:

    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;
    

    I wanted to add paddingToBottom because usually it is not needed that ScrollView is scrolled to the bottom till last pixel. But if you want that set paddingToBottom to zero.

    0 讨论(0)
  • 2020-12-23 22:07

    For Horizontal ScrollView (e.g. Carousels) replace isCloseToBottom function with isCloseToRight

    isCloseToRight = ({ layoutMeasurement, contentOffset, contentSize }) => {
        const paddingToRight = 20;
        return layoutMeasurement.width + contentOffset.x >= contentSize.width - paddingToRight;
    };
    
    0 讨论(0)
提交回复
热议问题