W przypadku aplikacji czatowej chcę, aby komponent ScrollView
przewinął się do dołu, ponieważ najnowsze wiadomości pojawiają się pod starszymi. Czy możemy dostosować pozycję przewijania z ScrollView
?Czy możliwe jest przewijanie ScrollView na dół?
Odpowiedz
Spróbuj ustawić właściwość contentOffset widoku przewijania na bieżącą wysokość zawartości.
Aby osiągnąć to, czego potrzebujesz, możesz to zrobić jako część zdarzenia onScroll. Może to jednak powodować złe wrażenia użytkownika, dlatego może okazać się bardziej przyjazne dla użytkownika, aby robić to tylko po dołączeniu nowej wiadomości.
-1; nie. Podobnie jak wiele odpowiedzi tutaj, powoduje to przewijanie "ScrollView" w dół do * pod * całą zawartością, zamiast przewijania do dołu. –
Trochę za późno ... ale spójrz na to pytanie. Scroll to top of ScrollView
ScrollView ma metodę "scrollTo".
Tak, na ScrollView jest dostępna metoda scrollTo, ale pytanie dotyczy właśnie przewijania w dół, co nie jest proste. – Southerneer
Możesz odwrócić widok przewijania/listy za pomocą react-native-invertible-scroll-view
module, a następnie po prostu wywołać ref.scrollTo(0)
, aby przewinąć do dołu.
Zainstalować moduł:
npm install --save react-native-invertible-scroll-view
następnie zaimportować komponent:
import InvertibleScrollView from 'react-native-invertible-scroll-view';
Następnie kliknąć na poniższy JSX zamiast ScrollView
:
<InvertibleScrollView inverted
ref={ref => { this.scrollView = ref; }}
onContentSizeChange={() => {
this.scrollView.scrollTo({y: 0, animated: true});
}}
>
{ /* content */ }
</InvertibleScrollView>
To działa, ponieważ react-native-invertible-scroll-view
Odwraca zawartość całego widoku. Zwróć uwagę, że dzieci widoku będą również renderować w odwrotnej kolejności niż normalne widoki - pierwsze dziecko pojawi się na dole na dole.
Metoda ta jest trochę hacky, ale nie mogłem znaleźć lepszy sposób
- najpierw dodać do swojego Scrollview ref.
- drugie dodać obojętne View przed zamknięciem tagu Scrollview
- uzyskać pozycję Y z tego manekina View
- Kiedy chcesz przejść do dolnego zwoju na stanowisko manekina View
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>
);
}
Nie jest to * całkiem * to, o co proszono; to przewijane jest na dół po stuknięciu, a nie przewijanie przewijania do dołu w miarę dodawania zawartości. W każdym razie 'scrollToBottom' sprawia, że takie podejście jest przestarzałe w nowszych wersjach React Native. –
Zastosowanie onContentSizeChange śledzić dolnej Y widoku przewijania (wysokość)
https://facebook.github.io/react-native/docs/scrollview.html#oncontentsizechange
var _scrollToBottomY
<ScrollView
onContentSizeChange={(contentWidth, contentHeight)=>{
_scrollToBottomY = contentHeight;
}}>
</ScrollView>
następnie użyć nazwy ref zdania przewijania jak
this.refs.scrollView.scrollTo(_scrollToBottomY);
Należy zauważyć, że powoduje to przewijanie widoku całkowicie do dołu, dlatego widok jest zasadniczo niewidoczny (chyba, że dodałeś coś do niego po pomiarze). Ma to sens, ponieważ kod przewija się na wysokość przewijanego obszaru, a nie do wysokości dzieci przepływających przez przewiany obszar (prawdopodobnie NIE tego, co chciał OP). Zamiast tego zobacz http://stackoverflow.com/a/39563193/1526986. – xixixao
Oto najprostsze rozwiązanie mogłem wykrzesać:
<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})
}}
/>
Kiedy używam tej lub innych podobnych odpowiedzi, powoduje to, że pozycje na liście znikają (wygląda na to, że przewijam _too_ daleko, ale nie jestem tego pewien). Przewijanie maleńkiego fragmentu sprawia, że wszystko pojawia się ponownie, i wygląda jakby było przesuwane z powrotem do widoku (stąd przewijanie teorii _too_ daleko). Jakiś oczywisty pomysł, dlaczego tak się dzieje? – tscizzle
ta odpowiada na pytanie: https://stackoverflow.com/a/39563100/1917250
Musisz stale przewijać do dołu strony, obliczając wysokość zawartości minus wysokość jej scrollView.
To jest poprawna odpowiedź na pytanie.Możesz być mądry, kiedy wykonać przewijanie, odpowiedź w odnośniku pokazuje, jak uzyskać potrzebne liczby. W szczególności, jeśli dodajesz komponenty do listy, wysokość zawartości nie będzie uwzględniać ich po wywołaniu komponentDidUpdate, więc chcesz pamiętać, że zamiast tego chcesz przewinąć i przewinąć na stronieContentSizeChange. – xixixao
Dla React Native 0.41 i później, można to zrobić za pomocą wbudowanego w scrollToEnd
metody:
<ScrollView
ref={ref => this.scrollView = ref}
onContentSizeChange={(contentWidth, contentHeight)=>{
this.scrollView.scrollToEnd({animated: true});
}}>
</ScrollView>
miałem podobny problem, ale po przeczytaniu tej strony (która daje mi ból głowy!) Znajduję this very nice npm package, które właśnie odwracają ListView i ułatwiają korzystanie z aplikacji do czatów !!
-1; to duplikaty [poprzednio opublikowana odpowiedź tutaj] (https://stackoverflow.com/a/32240057/1709587) (i jest również nieco zdezorientowana, to pytanie dotyczy 'ScrollView', a nie' ListView'). –
Nie wiem nic na temat reagowania natywnego, ale należy pamiętać, że czasami użytkownicy chcą przewinąć w górę, aby wyświetlić historię czatu. Pamiętaj, aby przewinąć czat tylko wtedy, gdy czat był już przewinięty do samego końca, gdy nadejdzie nowa wiadomość. – David
To jest dobry pomysł. Śledzimy ten problem tutaj: https://github.com/facebook/react-native/issues/107 –
Właśnie odpowiedziałem na podobne pytanie, proszę sprawdzić to tutaj - http://stackoverflow.com/a/32652967/ 1541508 – Kohver