2015-10-19 11 views
8

Próbuję użyć poziomego ScrollView w React Native dla Androida, gdzie pozycja początkowa znajduje się pośrodku przewijanych obrazów, a nie (0,0).Reaguj na natywną przewijarkę Android ScrollViewNie działa

Metoda wydaje się być poprawnie wywoływana wewnątrz componentDidMount, ale nic nie porusza się w aplikacji, nadal pokazuje się jako początek przewijania do końca w lewo.

Ponieważ to jest Android, nie mam dostępu do rekwizytów contentOffset lub ustawiłbym to bezpośrednio, zgodnie z dokumentacją. Oto kod:

'use strict'; 

var React = require('react-native'); 
var { 
    StyleSheet, 
    View, 
    Text, 
    ScrollView, 
    Component, 
} = React; 
var precomputeStyle = require('precomputeStyle'); 

class Carousel extends Component { 
    constructor(props, context) { 
    super(props, context); 
    //this.changeContent = this.changeContent.bind(this); 
    } 

    componentDidMount() { 
    this.myScroll.scrollTo(100); 
    console.log("called DidMount"); 
    } 

    render() { 
    return (
     <View style={{flex: 1}}> 
     <ScrollView ref={(ref) => this.myScroll = ref} 
      contentContainerStyle={styles.container} 
      horizontal={true} 
      pagingEnabled={true} 
      showsHorizontalScrollIndicator={false} 
      bounces={true} 
      onMomentumScrollEnd={this.onAnimationEnd} 
     > 
      {this.props.children} 
     </ScrollView> 
     </View> 
    ); 
    } 

    onAnimationEnd(e) { 
    console.log("curr offset: " + e.nativeEvent.contentOffset.x); 
    } 
} 

var styles = StyleSheet.create({ 
    container: { 
    flex: 1, 
    justifyContent: 'center', 
    }, 
    page: { 
    alignItems: 'center', 
    justifyContent: 'center', 
    borderWidth: 1, 
    }, 
}); 

module.exports = Carousel; 
+1

Czy możesz spróbować dodać również współrzędną Y? Na przykład. 'scrollTo (100, 0)'. – Felix

+0

Zrobiłem i problem pozostaje taki sam, brakująca współrzędna domyślnie wynosi zero, jeśli nie jest określona. –

+0

Myślę, że w rzeczywistości jest to 'scrollTo (y, x)' ale ta składnia jest przestarzała. Teraz jest to 'scrollTo ({x: n, y: n, animated: bool})' i jak wspomniał Rob, możesz pominąć 'x',' y' i 'animated' w zależności od twoich potrzeb. – PhilT

Odpowiedz

26

spotykam ten sam problem, a odpady kilka godzin w tym: 1 w android, Scrollview można przewijać tylko wtedy, gdy jego wielkość < zawartość Rozmiar 2 w reagują natywną Android, jeśli zadzwonisz scrollView.scrollTo() w componentDidMount, to nie będzie działać, becaus Scrollview posiada animację podczas tworzenia układu, można go znaleźć w ReactScrollView.java

protected void onLayout(boolean changed, int l, int t, int r, int b) { 
    // Call with the present values in order to re-layout if necessary 
    scrollTo(getScrollX(), getScrollY()); 
} 

więc należy opóźnić go po animacji

componentDidMount() { 
    InteractionManager.runAfterInteractions(() => { 
     this.myScroll.scrollTo(100); 
     console.log("called DidMount"); 
    }) 
} 
+1

Dziękuję bardzo! Jak zakończyłeś debugowanie tego? –

+2

To rozwiązanie działa, ale musiałem dodać opóźnienie w tej funkcji: '_.delay (() => this._scroll.scrollTo ({x: 1000, animated: false}), 100);' – Eldelshell

+0

Wystarczy użyć opóźnienie bez pracy menedżera interakcji dla ScrollView. Opublikuję odpowiedź z kodem, ponieważ miałem problem ze znalezieniem dobrego zasobu na ten temat. – PhilT

5

Działa na React Native 0.44.0. Dzięki za podpowiedź @Eldelshell. Wydaje się również działać z dowolną wartością limitu czasu. Przynajmniej na emulatorze. Stwierdziłem, że odpowiedź z udziałem InteractionManager.runAfterInteractions nie naprawiła problemu, ale może to różnica w wersjach.

componentDidMount() { 
    setTimeout(() => { 
    this._scroll.scrollTo({y: 100}) 
    }, 1) 
} 
+0

Ta odpowiedź zakłada, że ​​początkowa animacja ScrollView została zakończona w ciągu 1 ms. Może się tak zdarzyć przez większość czasu, ale nie jest to gwarantowane. Dlatego właśnie preferowane jest 'InteractionManager.runAfterInteractions()', a 'setTimeout()' jest nieco niechlujny. –

Powiązane problemy