tutorial support react framework example app react-native react-native-scrollview

react native - support - Detect ScrollView ha llegado al final



react native tutorial (7)

Tengo un Text con texto largo dentro de un ScrollView y quiero detectar cuándo el usuario se ha desplazado hasta el final del texto para poder habilitar un botón.

He estado depurando el objeto de evento del evento onScroll pero no parece haber ningún valor que pueda usar.


@Henrik R tiene razón. Pero también debes usar 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; }


A medida que las personas ayudaron aquí, agregaré el código simple que escriben para hacer llegar al principio y al final del evento, e hice una pequeña ilustración para simplificar las cosas.

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


Como una adición a la respuesta de Henrik R:

Si necesita saber si el usuario ha llegado al final del contenido en el momento del montaje (si el contenido puede o no ser demasiado largo, dependiendo del tamaño del dispositivo), aquí está mi solución:

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

en combinación con

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


Lo hice así:

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;

Quería agregar paddingToBottom porque generalmente no es necesario que ScrollView se desplace hacia abajo hasta el último píxel. Pero si quieres que el paddingToBottom sea cero.


Otra solución podría ser usar un ListView con una sola fila (su texto) que tenga el método onEndReached . Vea la documentación here


Para Horizontal ScrollView (por ejemplo, carruseles), reemplace la función isCloseToRight con isCloseToRight

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


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

como este reactivo-nativo 0.44