vertical scrolling react not horizontal flatlist example and react-native

react native - scrolling - ¿Es posible mantener un ScrollView desplazado hacia abajo?



react native scrollview scrollto (12)

Aquí está la solución más simple que pude reunir:

<ListView ref={ref => (this.listView = ref)} onLayout={event => { this.listViewHeight = event.nativeEvent.layout.height; }} onContentSizeChange={() => { this.listView.scrollTo({ y: this.listView.getMetrics().contentLength - this.listViewHeight }); }} />;

Para una aplicación tipo chat, quiero mantener un componente ScrollView desplazado hacia abajo, porque los mensajes más nuevos aparecen debajo de los más antiguos. ¿Podemos ajustar la posición de desplazamiento de un ScrollView ?


Este método es un poco hacky pero no pude encontrar una mejor manera

  1. Primero agregue una referencia a su ScrollView.
  2. En segundo lugar, agregue una vista ficticia antes de cerrar su etiqueta ScrollView
  3. Obtenga la posición y de esa vista ficticia
  4. Siempre que desee desplazarse hacia abajo, desplácese hasta la posición de la Vista ficticia

var footerY; //Y position of the dummy view render() { return ( <View> <ScrollView ref=''_scrollView''> // This is where all the things that you want to display in the scroll view goes // Below is the dummy View <View onLayout={(e)=> { footerY = e.nativeEvent.layout.y; }}/> </ScrollView> //Below is the button to scroll to the bottom <TouchableHighlight onPress={() => { this.refs._scrollView.scrollTo(footerY); }}> <Text>Scroll to Bottom</Text> </TouchableHighlight> </View> ); }


Esto responde a su pregunta: https://.com/a/39563100/1917250

Debe seguir desplazándose constantemente hasta la parte inferior de la página calculando la altura del contenido menos la altura de su scrollView.


Intente configurar la propiedad contentOffset de la vista de desplazamiento a la altura actual del contenido.

Para lograr lo que necesita, puede hacer esto como parte del evento onScroll. Sin embargo, esto puede provocar una mala experiencia del usuario, por lo que puede resultar más fácil de usar hacer esto solo cuando se agrega un nuevo mensaje.


Luché con esto por un tiempo y finalmente se me ocurrió algo que funcionó realmente bien y sin problemas para mí. Como muchos, probé .scrollToEnd en vano. La solución que funcionó para mí fue una combinación de onContentSizeChange , onLayout props y un poco más de pensamiento visual sobre "lo que realmente significaba desplazarse hacia abajo". La última parte me parece trivial ahora, pero me llevó una eternidad darme cuenta.

Dado que ScrollView tiene una altura fija, cuando la altura del contenido supera la altura del contenedor, prevHeight el desplazamiento restando el prevHeight (altura fija del ScrollView ) para el currHeight (la altura del contenido). Si puede imaginarlo visualmente, desplazándose a esa diferencia en el eje y, desliza la altura del contenido sobre su contenedor en ese desplazamiento. Aumenté mi desplazamiento e hice mi altura de contenido actual actual mi altura anterior y seguí calculando un nuevo desplazamiento.

Aquí está el código. Espero que ayude a alguien.

class ChatRoomCorrespondence extends PureComponent { currHeight = 0; prevHeight = 0; scrollHeight = 0; scrollToBottom = () => { this.refs.scrollView.getScrollResponder().scrollResponderScrollTo({ x: 0, y: this.scrollHeight, animated: true }); }; render() { return ( <ScrollView style={Styles.container} ref="scrollView" onContentSizeChange={(w, h) => { this.currHeight = h; if ( this.prevHeight > 0 && this.currHeight - this.scrollHeight > this.prevHeight ) { this.scrollHeight += this.currHeight - this.prevHeight; console.log("--------------------------------------------"); console.log("Curr: ", this.currHeight); console.log("Prev: ", this.prevHeight); console.log("Scroll: ", this.scrollHeight); this.prevHeight = this.currHeight; console.log("PREV: ", this.prevHeight); console.log("--------------------------------------------"); this.scrollToBottom(); } }} onLayout={ev => { // Fires once const fixedContentHeight = ev.nativeEvent.layout.height; this.prevHeight = fixedContentHeight; }} > <FlatList data={this.props.messages} renderItem={({ item }) => ( <ChatMessage text={item.text} sender={item.sender} time={item.time} username={this.props.username} /> )} keyExtractor={(item, index) => index.toString()} /> </ScrollView> ); } }


Para React Native 0.41 y posterior , puede hacer esto con el método incorporado scrollToEnd :

<ScrollView ref={ref => this.scrollView = ref} onContentSizeChange={(contentWidth, contentHeight)=>{ this.scrollView.scrollToEnd({animated: true}); }}> </ScrollView>


Puede invertir la vista de desplazamiento / lista usando el módulo react-native-invertible-scroll-view , luego simplemente llame a ref.scrollTo(0) para desplazarse hacia abajo.

Instalar el módulo:

import InvertibleScrollView from ''react-native-invertible-scroll-view'';

Luego importe el componente:

<InvertibleScrollView inverted ref={ref => { this.scrollView = ref; }} onContentSizeChange={() => { this.scrollView.scrollTo({y: 0, animated: true}); }} > { /* content */ } </InvertibleScrollView>

Luego use el siguiente JSX en lugar de un ScrollView :

<ScrollView ref="scrollView" onContentSizeChange={(width,height) => this.refs.scrollView.scrollTo({y:height})}> </ScrollView> // OR height - width

Esto funciona porque react-native-invertible-scroll-view voltea todo el contenido de la vista. Tenga en cuenta que los elementos secundarios de la vista también se mostrarán en el orden opuesto a una vista normal: el primer elemento secundario aparecerá en la parte inferior .


Supongo que es demasiado tarde para responder, ¡pero tengo un truco! Si usa FlatList , puede habilitar la propiedad inverted que vuelve a establecer la transform scale en -1 (que es aceptable para otros componentes de la lista como ScrollView ...). Cuando renderiza su FlatList con datos, ¡siempre estará en la parte inferior!


Tuve un problema similar, pero después de leer esta página (¡lo que me da dolor de cabeza!) ¡Encuentro este paquete npm muy agradable que simplemente invierte el ListView y facilita todo para una aplicación de chat!



Use onContentSizeChange para realizar un seguimiento de la parte inferior Y de la vista de desplazamiento (altura)

https://facebook.github.io/react-native/docs/scrollview.html#oncontentsizechange

var _scrollToBottomY <ScrollView onContentSizeChange={(contentWidth, contentHeight)=>{ _scrollToBottomY = contentHeight; }}> </ScrollView>

luego use el nombre de referencia de la vista de desplazamiento como

this.refs.scrollView.scrollTo(_scrollToBottomY);


prueba esta solución

xcode 10.0

RN: 56.0.0

npm install --save react-native-invertible-scroll-view