web-dev-qa-db-fra.com

Réagissez natif Android ScrollView scrollTo ne fonctionne pas

J'essaie d'utiliser un ScrollView horizontal dans React Native pour Android, où la position de départ est au milieu des images défilantes plutôt que (0,0). 

La méthode scrollTo semble être appelée correctement dans componentDidMount mais rien ne bouge dans l'application, elle indique toujours que le défilement commence complètement à gauche. 

Comme il s'agit d'Android, je n'ai pas accès aux accessoires contentOffset ou je le définirais directement, selon la documentation. Voici le 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

J'ai eu le même problème et j'ai perdu plusieurs heures sans rien faire:

  • 1: dans Android, ScrollView ne peut défiler que lorsque sa taille <la taille du contenu

  • 2: dans Android natif, si vous appelez ScrollView.scrollTo () dans composantDidMount, cela ne fonctionnera pas car ScrollView a une animation de présentation lors de la création, vous pouvez la trouver dans 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());
}

oui, vous devez attendre après l'animation

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

Cela fonctionne sur React Native 0.44.0. Merci pour l'allusion @Eldelshell. Il semble également fonctionner avec n'importe quelle valeur de délai d'attente. Au moins sur l'émulateur. J'ai trouvé que la réponse impliquant InteractionManager.runAfterInteractions n'a rien fait pour résoudre le problème, mais c'est peut-être une différence de version.

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

Je voulais éviter les retards et les minuteries, alors après un peu de fouille, j'ai découvert que l'utilisation de onLayout fonctionnait très bien:

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