Как сохранить положение прокрутки с помощью flatlist при повторном входе в реакцию?

Я новичок в реагировании на родной язык. Мне приходится сталкиваться с проблемой сохранения позиции flatlist при навигации вперед, а затем вернуться к этому экрану.

Текущее поведение
При перемещении вперед, а затем назад положение прокрутки теряется.

Ожидаемое поведение
При навигации по обширному списку элементов пользователь прокручивает список вниз и нажимает на какой-либо элемент. Приложение переходит к следующей странице, на которой отображаются детали продукта. Если пользователь решает вернуться назад, страница не прокручивается до предыдущей точки.

Ответ 1

Попробуйте обработать изменение положения прокрутки в состоянии:

<FlatList onScroll={this.handleScroll} />

метод handleScroll :

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

Затем вы можете использовать scrollToOffset (this.state.scrollPosition) при переходе назад.

Если вы используете реагирующую навигацию и хотите сохранить положение прокрутки после навигации, попробуйте этот метод:

componentDidMount() {
  this.props.navigation.addListener('willBlur', () => {
    const offset = this.state.scrollPosition
    // To prevent FlatList scrolls to top automatically,
    // we have to delay scroll to the original position 
    setTimeout(() => {
      this.flatList.scrollToOffset({ offset, animated: false })
    }, 500)
  })
}

Ответ 2

Я использую интерактивную навигацию для навигации между FlatList и представлением деталей. Я также использую реакцию-редукцию для отслеживания состояния. Вот этот процесс я последовал.

  • В основном слушайте изменения в навигаторе и сохраняйте в сокращении имя текущего маршрута
  • Когда вы выбираете элемент в своем FlatList, помните индекс выбранного элемента
  • Когда вы вернетесь в свой FlatList, подсчитайте смещение для этого индекса и прокрутите

Все это немного проще сказать, а затем в моем собственном Компоненте строки в моем FlatList являются переменными, что усложняет вычисление смещения, но вот пример, предполагающий, что ваши строки одинаковы

Мой компонент приложения, который отображает навигатор

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} />

Мой компонент с FlatList выглядит так

// 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}
       />
    )
}

Ответ 3

В Flatlist set scrollsToTop={false} это будет удерживать позицию при навигации по экрану с подробным описанием. Я использую Expo 25.