web-dev-qa-db-fra.com

Comment obtenir l'index actuellement visible dans la liste plate RN

J'ai une liste horizontale horizontale où chaque élément est width:300 Tout ce que j'essaie de faire, c'est d'obtenir l'index de l'élément actuellement visible.

<FlatList 
            onScroll={(e) => this.handleScroll(e)} 
            horizontal={true}
            data={this.state.data}
            renderItem...

J'ai essayé ceci:

handleScroll(event) {
    let index = Math.ceil(
      event.nativeEvent.contentOffset.x / 300
    );

Et quelque chose comme ça:

handleScroll(event) {
  let contentOffset = event.nativeEvent.contentOffset;
  let index = Math.floor(contentOffset.x / 300);

mais rien n'est précis, j'ai toujours un index vers le haut ou un index vers le bas.
Qu'est-ce que je fais mal et comment obtenir l'index actuel correct dans la liste plate?

Par exemple, j'arrive à lister l'élément qui est 8ème dans une liste mais j'obtiens l'index 9 ou 10.
enter image description here

18
1110

[~ # ~] upd [~ # ~] . merci à fzyzcjy pour avoir indiqué que onViewableItemsChanged ne devrait pas être mis à jour

Vous pouvez utiliser FlatList onViewableItemsChanged prop pour obtenir ce que vous voulez.

class Test extends React.Component {
  onViewableItemsChanged = ({ viewableItems, changed }) => {
    console.log("Visible items are", viewableItems);
    console.log("Changed in this iteration", changed);
  }

  render () => {
    return (
      <FlatList
        onViewableItemsChanged={this.onViewableItemsChanged }
        viewabilityConfig={{
          itemVisiblePercentThreshold: 50
        }}
      />
    )
  }
}

viewabilityConfig peut vous aider à faire ce que vous voulez avec les paramètres de visibilité. Dans l'exemple de code 50 signifie que l'élément est considéré comme visible s'il est visible sur plus de 50%.

La structure de configuration peut être trouvée ici

35
Roman Osypov
this.handleScroll = (event) => {
  let yOffset = event.nativeEvent.contentOffset.y
  let contentHeight = event.nativeEvent.contentSize.height
  let value = yOffset / contentHeight
}

<FlatList onScroll={this.handleScroll} />

Obtenez la valeur d'arrondi pour calculer le numéro de page/index.

5
Sujit

Merci beaucoup à la réponse la plus votée :) Cependant, cela ne fonctionne pas lorsque je l'essaie, ce qui génère une erreur indiquant que changing onViewableItemsChanged on the fly is not supported. Après quelques recherches, je trouve la solution ici . Voici le code complet qui peut s'exécuter sans erreur. Le point clé est que les deux configurations doivent être mises en tant que propriétés de classe au lieu d'être à l'intérieur de la fonction render ().

class MyComponent extends Component {  
  _onViewableItemsChanged = ({ viewableItems, changed }) => {
    console.log("Visible items are", viewableItems);
    console.log("Changed in this iteration", changed);
  };

  _viewabilityConfig = {
    itemVisiblePercentThreshold: 50
  };

  render() {
    return (
        <FlatList
          onViewableItemsChanged={this._onViewableItemsChanged}
          viewabilityConfig={this._viewabilityConfig}
          {...this.props}
        />
      </View>
    );
  }
}
5
fzyzcjy

Avec les réponses de @ fzyzcjy et @ Roman. Dans react, 16.8+, vous pouvez utiliser uscCallback pour gérer le changing onViewableItemsChanged on the fly is not supported Erreur.

function MyComponent(props) {
    const _onViewableItemsChanged = useCallback(({ viewableItems, changed }) => {
        console.log("Visible items are", viewableItems);
        console.log("Changed in this iteration", changed);
    }, []);

    const _viewabilityConfig = {
        itemVisiblePercentThreshold: 50
    }

    return <FlatList
            onViewableItemsChanged={_onViewableItemsChanged}
            viewabilityConfig={_viewabilityConfig}
            {...props}
        />;
}
1
tiran