Pour une application de type chat, je souhaite faire ScrollView
défiler un composant vers le bas, car les messages les plus récents apparaissent sous les plus anciens. Pouvons-nous ajuster la position de défilement de a ScrollView
?
Pour une application de type chat, je souhaite faire ScrollView
défiler un composant vers le bas, car les messages les plus récents apparaissent sous les plus anciens. Pouvons-nous ajuster la position de défilement de a ScrollView
?
Réponses:
Pour React Native 0.41 et versions ultérieures , vous pouvez le faire avec la scrollToEnd
méthode intégrée :
<ScrollView
ref={ref => {this.scrollView = ref}}
onContentSizeChange={() => this.scrollView.scrollToEnd({animated: true})}>
</ScrollView>
root
autrement, scrollToEnd n'est pas défini. iethis.scrollView.root.scrollToEnd
root
génère une erreur non définie.
ref={ref => {this.scrollView = ref}}
comme vous ne voulez pas retourner le devoir
Utilisez onContentSizeChange pour garder une trace du Y inférieur de la vue de défilement (hauteur)
https://facebook.github.io/react-native/docs/scrollview.html#oncontentsizechange
var _scrollToBottomY
<ScrollView
onContentSizeChange={(contentWidth, contentHeight)=>{
_scrollToBottomY = contentHeight;
}}>
</ScrollView>
puis utilisez le nom de référence de la vue de défilement comme
this.refs.scrollView.scrollTo(_scrollToBottomY);
Voici la solution la plus simple que je pourrais trouver:
<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
});
}}
/>;
Pour toute personne qui écrit un composant de fonction qui peut utiliser un hook,
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 })}
/>
);
};
essayez cette solution
xcode 10.0
IA: 56,0,0
<ScrollView ref="scrollView"
onContentSizeChange={(width,height) => this.refs.scrollView.scrollTo({y:height})}> </ScrollView> // OR height - width
ref=
? semble être une relique de développement Web
Au cas où quelqu'un en 2020 ou plus tard se demanderait comment y parvenir avec des composants fonctionnels. Voici comment j'ai fait:
ref={ref => scrollView = ref }
onContentSizeChange={() => scrollView.scrollToEnd({ animated: true })}>
Vous pouvez inverser l'affichage de défilement / liste à l'aide du react-native-invertible-scroll-view
module , puis simplement appeler ref.scrollTo(0)
pour faire défiler vers le bas.
Installez le module:
npm install --save react-native-invertible-scroll-view
Importez ensuite le composant:
import InvertibleScrollView from 'react-native-invertible-scroll-view';
Utilisez ensuite le JSX suivant au lieu d'un ScrollView
:
<InvertibleScrollView inverted
ref={ref => { this.scrollView = ref; }}
onContentSizeChange={() => {
this.scrollView.scrollTo({y: 0, animated: true});
}}
>
{ /* content */ }
</InvertibleScrollView>
Cela fonctionne car react-native-invertible-scroll-view
retourne tout le contenu de la vue. Notez que les enfants de la vue seront également rendus dans l'ordre opposé à une vue normale - le premier enfant apparaîtra en bas .
En fait, la réponse @Aniruddha ne fonctionne pas pour moi parce que j'utilise "react-native": "0.59.8"
et qu'elle this.scrollView.root.scrollToEnd
n'est pas définie
mais je l'ai compris et cela fonctionne this.scrollView.scrollResponderScrollToEnd({animated: true});
Si vous utilisez, 0.59.8
cela fonctionnera OU si vous utilisez une version ultérieure et cela fonctionne pour vous. veuillez ajouter des versions dans cette réponse afin que les autres n'aient pas de problèmes.
Code complet ici
<ScrollView
ref={ref => this.scrollView = ref}
onContentSizeChange={(contentWidth, contentHeight)=>{
this.scrollView.scrollResponderScrollToEnd({animated: true});
}}>
</ScrollView>
Cette méthode est un peu piratée mais je n'ai pas trouvé de meilleur moyen
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
rend des approches comme celle-ci obsolètes dans les nouvelles versions de React Native.
Cela répond à votre question: https://stackoverflow.com/a/39563100/1917250
Vous devez continuer à faire défiler constamment vers le bas de la page en calculant la hauteur du contenu moins la hauteur de son scrollView.
Si vous utilisez TypeScript, vous devez le faire
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>
Je me suis battu avec ça pendant un moment et j'ai finalement trouvé quelque chose qui fonctionnait vraiment bien et qui fonctionnait bien pour moi. Comme beaucoup, j'ai essayé .scrollToEnd
en vain. La solution qui a fonctionné pour moi était une combinaison de onContentSizeChange
, onLayout
accessoires et un peu plus penser visuellement sur « ce défilement vers le bas » signifiait vraiment. La dernière partie me semble triviale maintenant, mais il m'a fallu une éternité pour comprendre.
Étant donné que le ScrollView
a une hauteur fixe, lorsque la hauteur du contenu dépasse la hauteur du conteneur, j'ai calculé le décalage en soustrayant la prevHeight
(hauteur fixe du ScrollView
) pour le currHeight
(la hauteur du contenu). Si vous pouvez l'imaginer visuellement, en faisant défiler jusqu'à cette différence sur l'axe des y, faites glisser la hauteur du contenu sur son conteneur de ce décalage. J'ai incrémenté mon décalage et fait de la hauteur de contenu actuelle ma hauteur précédente et j'ai continué à calculer un nouveau décalage.
Voici le code. J'espère que ça aide quelqu'un.
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>
);
}
}
Je suppose qu'il est trop tard pour répondre mais j'ai eu un hack! Si vous utilisez , FlatList
vous pouvez activer la inverted
propriété qui revient à la mise transform scale
à -1
( ce qui est acceptable pour d' autres composants de la liste comme ScrollView
...). Lorsque vous effectuez le rendu FlatList
avec des données, il sera toujours en bas!
Essayez de définir la propriété contentOffset de la vue de défilement sur la hauteur actuelle du contenu.
Pour accomplir ce dont vous avez besoin, vous pouvez le faire dans le cadre de l'événement onScroll. Cependant, cela peut entraîner une mauvaise expérience utilisateur, il peut donc s'avérer plus convivial de ne le faire que lorsqu'un nouveau message est ajouté.
ScrollView
vers le bas tout son contenu, plutôt que de simplement faire défiler vers le bas.
J'ai eu un problème similaire, mais après avoir lu cette page (ce qui me donne mal à la tête!) Je trouve ce très joli package npm qui vient d'inverser la ListView et facilite tout pour une application de chat !!
ScrollView
, pas `ListView`).
Un peu tard ... mais regardez cette question. Faire défiler vers le haut de ScrollView
ScrollView a une méthode "scrollTo".