2015-03-27 25 views
47

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ół?

+2

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

+0

To jest dobry pomysł. Śledzimy ten problem tutaj: https://github.com/facebook/react-native/issues/107 –

+0

Właśnie odpowiedziałem na podobne pytanie, proszę sprawdzić to tutaj - http://stackoverflow.com/a/32652967/ 1541508 – Kohver

Odpowiedz

-1

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.

+0

-1; nie. Podobnie jak wiele odpowiedzi tutaj, powoduje to przewijanie "ScrollView" w dół do * pod * całą zawartością, zamiast przewijania do dołu. –

-3

Trochę za późno ... ale spójrz na to pytanie. Scroll to top of ScrollView

ScrollView ma metodę "scrollTo".

+1

Tak, na ScrollView jest dostępna metoda scrollTo, ale pytanie dotyczy właśnie przewijania w dół, co nie jest proste. – Southerneer

2

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.

0

Metoda ta jest trochę hacky, ale nie mogłem znaleźć lepszy sposób

  1. najpierw dodać do swojego Scrollview ref.
  2. drugie dodać obojętne View przed zamknięciem tagu Scrollview
  3. uzyskać pozycję Y z tego manekina View
  4. 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> 
 
    ); 
 
    }

+0

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. –

22

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); 
+1

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

17

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}) 
    }} 
/> 
+1

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

0

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.

+0

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

42

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> 
-1

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 !!

+0

-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'). –