ios - pagingenabled - scrollview keyboard react native
Obtener la posiciĆ³n de desplazamiento actual de ScrollView en React Native (8)
Así es como terminó obteniendo la posición de desplazamiento actual en vivo desde la vista. Todo lo que estoy haciendo es usar el detector de eventos on scroll y scrollEventThrottle. Luego lo paso como un evento para manejar la función de desplazamiento que hice y actualizo mis accesorios.
export default class Anim extends React.Component {
constructor(props) {
super(props);
this.state = {
yPos: 0,
};
}
handleScroll(event){
this.setState({
yPos : event.nativeEvent.contentOffset.y,
})
}
render() {
return (
<ScrollView onScroll={this.handleScroll.bind(this)} scrollEventThrottle={16} />
)
}
}
¿Es posible obtener la posición de desplazamiento actual o la página actual de un componente
<ScrollView>
en React Native?
Entonces algo como:
<ScrollView
horizontal={true}
pagingEnabled={true}
onScrollAnimationEnd={() => {
// get this scrollview''s current page or x/y scroll position
}}>
this.state.data.map(function(e, i) {
<ImageCt key={i}></ImageCt>
})
</ScrollView>
Creo que
contentOffset
le dará un objeto que contiene el desplazamiento de desplazamiento superior izquierdo:
http://facebook.github.io/react-native/docs/scrollview.html#contentoffset
Descargo de responsabilidad: lo que sigue es principalmente el resultado de mi propia experimentación en React Native 0.50.
En la
documentación de
ScrollView
,
actualmente falta mucha de la información que se cubre a continuación;
por ejemplo,
onScrollEndDrag
está completamente indocumentado.
Dado que todo aquí depende de un comportamiento indocumentado, desafortunadamente no puedo prometer que esta información seguirá siendo correcta dentro de un año o incluso un mes.
Además, todo lo que se muestra a continuación supone una vista de desplazamiento puramente vertical cuyo desplazamiento y nos interesa; La traducción a las compensaciones x , si es necesario, es un ejercicio fácil para el lector.
Varios controladores de eventos en un
ScrollView
toman un
event
y le permiten 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 cuadro mientras el usuario se desplaza, en cada cuadro mientras la vista de desplazamiento se desliza después de que el usuario lo suelta, en el cuadro 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 cuadro cambiante (por ejemplo, debido a la rotación de paisaje a retrato).
En iOS
Se dispara mientras el usuario arrastra o mientras la vista de desplazamiento se desliza, a cierta 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 controlador
onScroll
también se activará cuando se
onScroll
después de deslizarse.
Sin embargo, si el usuario arrastra y luego suelta la vista de desplazamiento mientras está parado,
no se
garantiza que
onScroll
dispare para la posición final a menos que
scrollEventThrottle
se haya configurado de manera que
onScroll
dispare cada cuadro de desplazamiento.
Hay un costo de rendimiento para configurar
scrollEventThrottle={16}
que se puede reducir estableciéndolo en un número mayor.
Sin embargo, esto significa que
onScroll
no disparará cada cuadro.
onMomentumScrollEnd
Se dispara cuando la vista de desplazamiento se detiene después del deslizamiento. No se dispara en absoluto si el usuario suelta la vista de desplazamiento mientras está parado de modo que no se desliza.
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 del desplazamiento 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 marco de
ScrollView
debido a la rotación, y no desea aceptar la penalización de rendimiento en Android al configurar
scrollEventThrottle
en 16), y necesita para manejar los cambios en el
contenido
en la vista de desplazamiento también, entonces es un verdadero desastre.
El caso más simple es si solo necesita manejar Android;
solo usa
onScroll
:
<ScrollView
onScroll={event => {
this.yOffset = event.nativeEvent.contentOffset.y
}}
>
Para admitir adicionalmente iOS,
si
está contento de disparar el controlador
onScroll
cada cuadro y aceptar las implicaciones de rendimiento de eso, y
si
no necesita manejar los cambios de cuadro, entonces es solo un poco más complicado:
<ScrollView
onScroll={event => {
this.yOffset = event.nativeEvent.contentOffset.y
}}
scrollEventThrottle={16}
>
Para reducir la sobrecarga de rendimiento en iOS y al mismo tiempo garantizar que
scrollEventThrottle
cualquier posición en la que se establezca la vista de desplazamiento, podemos aumentar
scrollEventThrottle
y además proporcionar un controlador
onScrollEndDrag
:
<ScrollView
onScroll={event => {
this.yOffset = event.nativeEvent.contentOffset.y
}}
onScrollEndDrag={event => {
this.yOffset = event.nativeEvent.contentOffset.y
}}
scrollEventThrottle={160}
>
Pero si queremos manejar los cambios en el marco (por ejemplo, porque permitimos que el dispositivo gire, cambiando la altura disponible para el marco de la vista de desplazamiento) y / o los cambios de contenido, entonces debemos implementar adicionalmente tanto
onContentSizeChange
como en
onLayout
para realizar un seguimiento de la altura tanto del marco de la vista de desplazamiento como de su contenido, y así calcular continuamente el desplazamiento
máximo
posible e inferir cuando el desplazamiento se ha reducido automáticamente debido a un cambio de tamaño de contenido o marco:
<ScrollView
onLayout={event => {
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 funcionará correctamente en los casos en que cambie simultáneamente 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 característica se agregue dentro del marco en sí , creo que es lo mejor que cualquiera puede hacer.
En cuanto a la página, estoy trabajando en un componente de orden superior que utiliza básicamente los métodos anteriores para hacer exactamente esto. En realidad, lleva solo un poco de tiempo llegar a las sutilezas, como el diseño inicial y los cambios de contenido. No afirmaré haberlo hecho ''correctamente'', pero en cierto sentido consideraría la respuesta correcta para usar un componente que lo haga con cuidado y coherencia.
Ver: react-native-paged-scroll-view . ¡Me encantaría recibir comentarios, incluso si es que lo he hecho todo mal!
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 accesorio
scrollEventThrottle
, así:
<ScrollView onScroll={this.handleScroll} scrollEventThrottle={16} >
<Text>
Be like water my friend …
</Text>
</ScrollView>
Y el controlador de eventos:
handleScroll: function(event: Object) {
console.log(event.nativeEvent.contentOffset.y);
},
Tenga en cuenta que puede encontrarse con problemas de rendimiento. Ajuste el acelerador en consecuencia. 16 te da la mayoría de las actualizaciones. 0 solo uno.
Para obtener la x / y después de que el desplazamiento finalizara como lo solicitaban las preguntas originales, la forma más fácil es probablemente esta:
<ScrollView
horizontal={true}
pagingEnabled={true}
onMomentumScrollEnd={(event) => {
// scroll animation ended
console.log(e.nativeEvent.contentOffset.x);
console.log(e.nativeEvent.contentOffset.y);
}}>
...content
</ScrollView>
Si desea obtener simplemente la posición actual (por ejemplo, cuando se presiona algún botón) en lugar de rastrearla cada vez que el usuario se desplaza, invocar un oyente
onScroll
causará problemas de rendimiento.
Actualmente, la forma más eficaz de obtener simplemente la posición de desplazamiento actual es usar el paquete
react-native-invoke
.
Hay un ejemplo para esto exactamente, pero el paquete hace muchas otras cosas.
Lea sobre esto aquí. https://medium.com/@talkol/invoke-any-native-api-directly-from-pure-javascript-in-react-native-1fb6afcdf57d#.68ls1sopd
Tratar.
<ScrollView onScroll={this.handleScroll} />
Y entonces:
handleScroll: function(event: Object) {
console.log(event.nativeEvent.contentOffset.y);
},