Saltar al contenido

Obtenga la posición de desplazamiento actual de ScrollView en React Native

Tenemos el hallazgo a este rompecabezas, o por lo menos eso deseamos. Si sigues con interrogantes dínoslo, que sin dudas

Solución:

Tratar.


Y luego:

handleScroll: function(event: Object) 
 console.log(event.nativeEvent.contentOffset.y);
,

Descargo de responsabilidad: lo que sigue es principalmente el resultado de mi propia experimentación en React Native 0.50. los ScrollView actualmente a la documentación le falta mucha de la información cubierta a continuación; por ejemplo onScrollEndDrag está completamente indocumentado. Dado que todo aquí se basa en un comportamiento no documentado, lamentablemente no puedo prometer que esta información seguirá siendo correcta dentro de un año o incluso un mes.

Además, todo lo siguiente asume una vista de desplazamiento puramente vertical cuyo y compensación que nos interesa; traduciendo a X compensaciones, si es necesario, es un ejercicio fácil para el lector.


Varios controladores de eventos en un ScrollView toma un event y le permite obtener la posición de desplazamiento actual a través de event.nativeEvent.contentOffset.y. Algunos de estos controladores tienen un comportamiento ligeramente diferente entre Android e iOS, como se detalla a continuación.

onScroll

En Android

Dispara cada fotograma mientras el usuario se desplaza, en cada fotograma mientras la vista de desplazamiento se desliza después de que el usuario la suelta, en el fotograma final cuando la vista de desplazamiento se detiene y también cada vez que el desplazamiento de la vista de desplazamiento cambia como resultado de su marco cambiando (por ejemplo, debido a la rotación de paisaje a retrato).

En iOS

Se activa mientras el usuario arrastra o mientras la vista de desplazamiento se desliza, con una frecuencia determinada por scrollEventThrottle y como máximo una vez por cuadro cuando scrollEventThrottle=16. Si el usuario suelta la vista de desplazamiento mientras tiene suficiente impulso para deslizarse, el onScroll el guía también disparará cuando se detenga después de planear. Sin embargo, si el usuario arrastra y luego suelta la vista de desplazamiento mientras está estacionaria, onScroll es no garantizado para disparar a la posición final a menos que scrollEventThrottle se ha fijado de tal manera que onScroll dispara cada cuadro de desplazamiento.

Hay un costo de rendimiento para establecer scrollEventThrottle=16 que se puede reducir ajustándolo a un número mayor. Sin embargo, esto significa que onScroll no disparará cada fotograma.

onMomentumScrollEnd

Se activa cuando la vista de desplazamiento se detiene después de deslizarse. No se dispara en absoluto si el usuario suelta la vista de desplazamiento mientras está estacionaria de modo que no se deslice.

onScrollEndDrag

Se activa cuando el usuario deja de arrastrar la vista de desplazamiento, independientemente de si la vista de desplazamiento se deja estacionaria o comienza a deslizarse.


Dadas estas diferencias de comportamiento, la mejor manera de realizar un seguimiento de la compensación depende de sus circunstancias precisas. En el caso más complicado (debe ser compatible con Android e iOS, incluido el manejo de cambios en el ScrollViewmarco debido a la rotación, y no desea aceptar la penalización de rendimiento en Android por la configuración scrollEventThrottle a 16), y necesita manejar los cambios en el contenido en la vista de desplazamiento también, entonces es un maldito desastre.

El caso más sencillo es si solo necesitas manejar Android; Solo usa onScroll:

  
    this.yOffset = event.nativeEvent.contentOffset.y
  
>

Para admitir adicionalmente iOS, si estás feliz de despedir el onScroll manejar cada cuadro y aceptar las implicaciones de rendimiento de eso, y si no necesita manejar los cambios de marco, entonces solo es un poco más complicado:

  
    this.yOffset = event.nativeEvent.contentOffset.y
  
  scrollEventThrottle=16
>

Para reducir la sobrecarga de rendimiento en iOS y al mismo tiempo garantizar que registremos cualquier posición en la que se asiente la vista de desplazamiento, podemos aumentar scrollEventThrottle y además proporcionar una onScrollEndDrag manipulador:

  
    this.yOffset = event.nativeEvent.contentOffset.y
  
  onScrollEndDrag=event =>  
    this.yOffset = event.nativeEvent.contentOffset.y
  
  scrollEventThrottle=160
>

Pero si queremos manejar cambios de marco (por ejemplo, porque permitimos que el dispositivo gire, cambiando la altura disponible para el marco de la vista de desplazamiento) y/o cambios de contenido, entonces debemos implementar ambos onContentSizeChange y onLayout para realizar un seguimiento de la altura del marco de la vista de desplazamiento y su contenido, y así calcular continuamente el máximo desplazamiento posible e inferir cuando el desplazamiento se ha reducido automáticamente debido a un cambio de tamaño de marco o contenido:

 
    this.frameHeight = event.nativeEvent.layout.height;
    const maxOffset = this.contentHeight - this.frameHeight;
    if (maxOffset < this.yOffset) 
      this.yOffset = maxOffset;
    
  
  onContentSizeChange=(contentWidth, contentHeight) => 
    this.contentHeight = contentHeight;
    const maxOffset = this.contentHeight - this.frameHeight;
    if (maxOffset < this.yOffset) 
      this.yOffset = maxOffset;
    
  
  onScroll=event =>  
    this.yOffset = event.nativeEvent.contentOffset.y;
  
  onScrollEndDrag=event =>  
    this.yOffset = event.nativeEvent.contentOffset.y;
  
  scrollEventThrottle=160
>

Sí, es bastante horrible. Tampoco estoy 100% seguro de que siempre funcione bien en los casos en los que simultaneamente cambiar el tamaño del marco y el contenido de la vista de desplazamiento. Pero es lo mejor que se me ocurre, y hasta que esta función se agregue dentro del propio marco, creo que es lo mejor que cualquiera puede hacer.

La respuesta de Brad Oyler es correcta. Pero solo recibirá un evento. Si necesita obtener actualizaciones constantes de la posición de desplazamiento, debe configurar el scrollEventThrottle apoyo, así:


  
    Be like water my friend …
  

Y el controlador de eventos:

handleScroll: function(event: Object) 
  console.log(event.nativeEvent.contentOffset.y);
,

Tenga en cuenta que podría encontrarse con problemas de rendimiento. Ajuste el acelerador en consecuencia. 16 te ofrece la mayor cantidad de actualizaciones. 0 solo uno.

Sección de Reseñas y Valoraciones

Si eres capaz, eres capaz de dejar un escrito acerca de qué le añadirías a este tutorial.

¡Haz clic para puntuar esta entrada!
(Votos: 2 Promedio: 4.5)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *