web-dev-qa-db-de.com

Reagieren Sie native Android ScrollView-ScrollTo, um nicht zu funktionieren

Ich versuche, ein horizontales ScrollView in React Native für Android zu verwenden, wobei die Startposition in der Mitte der Bildlaufbilder liegt und nicht (0,0). 

Die scrollTo-Methode scheint innerhalb von componentDidMount korrekt aufgerufen zu werden, bewegt sich jedoch in der Anwendung nicht und zeigt immer noch den Bildlauf ganz nach links. 

Da dies Android ist, habe ich keinen Zugriff auf contentOffset-Requisiten, oder ich würde das gemäß der Dokumentation direkt festlegen. Hier ist der Code:

'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;
19
Rob M

Ich hatte das gleiche Problem und verschwendete mehrere Stunden, nein:

  • 1: In Android kann ScrollView nur dann scrollen, wenn seine Größe <Inhalt ist

  • 2: In reaktivem Android kann ein Aufruf von ScrollView.scrollTo () in componentDidMount nicht ausgeführt werden, da ScrollView beim Erstellen eine Layoutanimation enthält

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());
}

sie müssen es also nach der Animation verschieben

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

Dies funktioniert bei React Native 0.44.0. Danke für den Hinweis @Eldelshell. Es scheint auch mit jedem Timeout-Wert zu funktionieren. Zumindest auf dem Emulator. Ich fand, dass die Antwort, die InteractionManager.runAfterInteractions betraf, nichts zur Lösung des Problems beigetragen hat, aber das ist vielleicht ein Unterschied in den Versionen.

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

Ich wollte Verzögerungen und Timer vermeiden, so dass ich nach etwas Graben fand, dass die Verwendung von onLayout sehr reibungslos funktioniert:

scrollToInitialPosition = () => {
  this.scrollViewRef.scrollTo({ y: 100 });
}
...
<ScrollView
  ref={(ref) => { this.scrollViewRef = ref; }}
  onLayout={this.scrollToInitialPosition}
/>
0