Für eine Chat-ähnliche App möchte ich eine ScrollView
Komponente nach unten scrollen lassen, da die neuesten Nachrichten unter den älteren angezeigt werden. Können wir die Bildlaufposition von a anpassen ScrollView
?
Für eine Chat-ähnliche App möchte ich eine ScrollView
Komponente nach unten scrollen lassen, da die neuesten Nachrichten unter den älteren angezeigt werden. Können wir die Bildlaufposition von a anpassen ScrollView
?
Antworten:
Für React Native 0.41 und höher können Sie dies mit der integrierten scrollToEnd
Methode tun :
<ScrollView
ref={ref => {this.scrollView = ref}}
onContentSizeChange={() => this.scrollView.scrollToEnd({animated: true})}>
</ScrollView>
root
sonst verwenden, scrollToEnd ist undefiniert. dhthis.scrollView.root.scrollToEnd
root
tatsächlich einen undefinierten Fehler aus.
ref={ref => {this.scrollView = ref}}
da Sie die Aufgabe nicht zurückgeben möchten
Verwenden Sie onContentSizeChange, um das untere Y der Bildlaufansicht (Höhe) zu verfolgen.
https://facebook.github.io/react-native/docs/scrollview.html#oncontentsizechange
var _scrollToBottomY
<ScrollView
onContentSizeChange={(contentWidth, contentHeight)=>{
_scrollToBottomY = contentHeight;
}}>
</ScrollView>
Verwenden Sie dann den Referenznamen der Bildlaufansicht wie
this.refs.scrollView.scrollTo(_scrollToBottomY);
Hier ist die einfachste Lösung, die ich aufbringen könnte:
<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
});
}}
/>;
Für alle, die Funktionskomponenten schreiben, die Hook verwenden können,
import React, { useRef } from 'react';
import { ScrollView } from 'react-native';
const ScreenComponent = (props) => {
const scrollViewRef = useRef();
return (
<ScrollView
ref={scrollViewRef}
onContentSizeChange={() => scrollViewRef.current.scrollToEnd({ animated: true })}
/>
);
};
Versuchen Sie diese Lösung
xcode 10.0
RN: 56.0.0
<ScrollView ref="scrollView"
onContentSizeChange={(width,height) => this.refs.scrollView.scrollTo({y:height})}> </ScrollView> // OR height - width
ref=
? scheint wie ein Web-
Sie können die Bildlauf- / Listenansicht mithilfe des react-native-invertible-scroll-view
Moduls umkehren und dann einfach aufrufen, ref.scrollTo(0)
um nach unten zu scrollen.
Installieren Sie das Modul:
npm install --save react-native-invertible-scroll-view
Importieren Sie dann die Komponente:
import InvertibleScrollView from 'react-native-invertible-scroll-view';
Verwenden Sie dann die folgende JSX anstelle von ScrollView
:
<InvertibleScrollView inverted
ref={ref => { this.scrollView = ref; }}
onContentSizeChange={() => {
this.scrollView.scrollTo({y: 0, animated: true});
}}
>
{ /* content */ }
</InvertibleScrollView>
Dies funktioniert, weil react-native-invertible-scroll-view
der gesamte Inhalt der Ansicht umgedreht wird. Beachten Sie, dass die untergeordneten Elemente der Ansicht auch in der entgegengesetzten Reihenfolge zu einer normalen Ansicht gerendert werden. Das erste untergeordnete Element wird unten angezeigt .
Für den Fall, dass sich jemand im Jahr 2020 oder später fragt, wie dies mit Funktionskomponenten erreicht werden kann. So habe ich es gemacht:
ref={ref => scrollView = ref }
onContentSizeChange={() => scrollView.scrollToEnd({ animated: true })}>
Eigentlich hat die Antwort von @Aniruddha bei mir nicht funktioniert, weil ich sie benutze "react-native": "0.59.8"
und this.scrollView.root.scrollToEnd
auch undefiniert bin
aber ich habe es herausgefunden und das funktioniert this.scrollView.scrollResponderScrollToEnd({animated: true});
Wenn Sie 0.59.8
dies verwenden, funktioniert dies ODER wenn Sie eine spätere Version verwenden und dies für Sie funktioniert. Bitte fügen Sie Versionen in diese Antwort ein, damit andere keine Probleme bekommen.
Vollständiger Code hier
<ScrollView
ref={ref => this.scrollView = ref}
onContentSizeChange={(contentWidth, contentHeight)=>{
this.scrollView.scrollResponderScrollToEnd({animated: true});
}}>
</ScrollView>
Diese Methode ist ein bisschen hacky, aber ich konnte keinen besseren Weg finden
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>
);
}
scrollToBottom
solche Ansätze in neueren Versionen von React Native überholt.
Dies beantwortet Ihre Frage: https://stackoverflow.com/a/39563100/1917250
Sie müssen ständig zum Ende der Seite scrollen, indem Sie die Höhe des Inhalts abzüglich der Höhe der scrollView berechnen.
Wenn Sie TypeScript verwenden, müssen Sie dies tun
interface Props extends TextInputProps {
scrollRef?: any;
}
export class Input extends React.Component<Props, any> {
scrollRef;
constructor(props) {
this.scrollRef = React.createRef();
}
<ScrollView
ref={ref => (this.scrollRef = ref)}
onContentSizeChange={() => {
this.scrollRef.scrollToEnd();
}}
>
</ScrollView>
Ich habe eine Weile damit gekämpft und mir schließlich etwas ausgedacht, das für mich wirklich gut und reibungslos funktioniert hat. Wie viele habe ich erfolglos versucht .scrollToEnd
. Die Lösung, die für mich funktionierte, war eine Kombination aus onContentSizeChange
:onLayout
Requisiten und ein bisschen mehr denken visuell über „was auf den Boden Scrollen“ wirklich bedeutete. Der letzte Teil scheint mir jetzt trivial, aber ich habe ewig gebraucht, um es herauszufinden.
Da das ScrollView
eine feste Höhe hat, berechnete ich den Versatz, wenn die Inhaltshöhe über die Höhe des Containers geht, indem ich die prevHeight
(feste Höhe des ScrollView
) für die currHeight
(die Inhaltshöhe) subtrahiere . Wenn Sie es sich visuell vorstellen können, schieben Sie beim Scrollen zu diesem Unterschied in der y-Achse die Inhaltshöhe um diesen Versatz über den Container. Ich habe meinen Versatz erhöht und meine jetzt aktuelle Inhaltshöhe zu meiner vorherigen Höhe gemacht und einen neuen Versatz berechnet.
Hier ist der Code. Hoffe es hilft jemandem.
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>
);
}
}
Ich denke, es ist zu spät, um zu antworten, aber ich habe einen Hack! Wenn Sie verwenden FlatList
Sie aktivieren inverted
Eigenschaft , die zur Einstellung fällt zurück transform scale
auf -1
(die für andere Liste Komponenten wie akzeptabel ist ScrollView
...). Wenn Sie Ihre FlatList
Daten rendern, werden diese immer ganz unten angezeigt!
Versuchen Sie, die contentOffset- Eigenschaft der Bildlaufansicht auf die aktuelle Höhe des Inhalts festzulegen .
Um das zu erreichen, was Sie benötigen, können Sie dies im Rahmen des onScroll-Ereignisses tun. Dies kann jedoch zu einer schlechten Benutzererfahrung führen, sodass es sich als benutzerfreundlicher erweisen kann, dies nur zu tun, wenn eine neue Nachricht angehängt wird.
ScrollView
nach unten gescrollt wird, anstatt nur nach unten zu scrollen.
Ich hatte ein ähnliches Problem, aber nachdem ich diese Seite gelesen habe (was mir Kopfschmerzen bereitet !), Finde ich dieses sehr schöne npm-Paket, das einfach die ListView invertiert und alles für eine Chat-Anwendung einfach macht !!
ScrollView
bezieht sich auf eine , nicht auf "ListView").
Ein bisschen spät ... aber sieh dir diese Frage an. Scrollen Sie zum Anfang von ScrollView
ScrollView verfügt über eine "scrollTo" -Methode.