web-dev-qa-db-fra.com

Comment conserver la position de défilement en utilisant flatlist lors de la navigation dans réagit natif?

Je suis nouveau pour réagir natif. J'ai du mal à conserver la position de flatlist lors de la navigation en avant, puis à revenir à cet écran. 

Comportement actuel
Lorsque vous naviguez en avant et en arrière, la position de défilement est perdue. 

Comportement prévisible
Lorsqu'il navigue dans une longue liste d'éléments, l'utilisateur la fait défiler et clique sur un élément. L'application passe à la page suivante qui affiche les détails du produit. Si l'utilisateur décide de revenir en arrière, la page ne passe pas au point précédent. 

9
Pulkit Aggarwal

Essayez de gérer la position du défilement en changeant d'état:

<FlatList onScroll={this.handleScroll} />

handleScroll méthode:

handleScroll: function(event: Object) {
 this.setState({ scrollPosition: event.nativeEvent.contentOffset.y });
}

Ensuite, vous pouvez utiliser scrollToOffset (this.state.scrollPosition) lorsque vous revenez en arrière.

9
Marcos Demétrio

J'utilise react-navigation pour naviguer entre une FlatList et une vue détaillée. J'utilise aussi react-redux pour suivre l'état. Voici le processus que j'ai suivi.

  • Écoutez les modifications apportées au navigateur et enregistrez dans le nom de l’itinéraire actuel.
  • Lorsque vous sélectionnez un élément dans votre FlatList, rappelez-vous l’index de l’élément sélectionné
  • Lorsque vous revenez à votre FlatList, calculez le décalage pour cet index et faites défiler

Tout cela est un peu plus facile à dire qu'à faire et dans mon propre composant, les lignes de ma FlatList sont variables, ce qui complique le calcul du décalage mais voici un exemple en supposant que vos lignes sont identiques

Mon composant App qui rend le navigateur

handleNavigationStateChange = (prevState, newState) => {
    this._getCurrentRouteName(newState)
}

_getCurrentRouteName = (navState) => {
    if (navState.hasOwnProperty('index')) {
        this._getCurrentRouteName(navState.routes[navState.index])
    } else {
        // This is my redux action to save route name
        this.props.updateCurrentRoute( navState.routeName )
    }
}

<AppNavigator onNavigationStateChange={this.handleNavigationStateChange} />

Mon composant avec la FlatList ressemble à ceci

// Renders a row for the FlatList with TouchableHighlight to call viewCreation
renderItem = ( row ) => {
    let creation = row.item
    return (
        <CreationCard onPress={this.viewCreation} index={row.index} creation={creation} />
    )
}

viewCreation = ( index ) => {
    // Get the creation
    let currentCreation = this.props.creations[index]
    // Another reducer saves both my item and index that was selected
    this.props.setSelectedIndex(currentCreation, index)
    // Navigate to the details screen
    this.props.navigation.navigate('CreationDetailScreen')
}

// Assuming all rows are 50 height
getItemLayout = (data, index) => {
    return {length: 50, offset: 50 * index, index}
}

// We mapped the 'currentRoute' property to this component so check
// the props when the component receives new ones.
componentWillReceiveProps( nextProps ){
    // If the currentRoute matches the route for this screen
    if( nextProps.currentRoute === 'CreationListScreen' ){
        // If we also know the last index that was selected on this page
        if( this.props.lastCreationIndex ){
            // Calculate the offset for the last index selected
            let y = this.props.lastCreationIndex * 50
            // and finally scroll to the offset
            this._flatList.scrollToOffset({
                offset: y,
                animated: true
            })
        }
    }
}


// IMPORTANT to include getItemLayout
render(){
    return(
    <FlatList
       ref={(fl) => this._flatList = fl}
       data={this.props.creations}
       renderItem={this.renderItem}
       getItemLayout={this.getItemLayout}
       keyExtractor={creation => creation.id}
       />
    )
}
1
Kerkness