如何在回复本地导航时使用平面列表保持滚动位置?

时间:2018-01-02 12:41:42

标签: javascript reactjs react-native

我是新来的本地人。我在向前导航时保持平面列表的位置时遇到问题,然后回到该屏幕。

目前的行为
向前导航然后向后导航时,滚动位置将丢失。

预期行为
在广泛的项目列表中导航时,用户向下滚动列表并单击某个项目。该应用程序转到显示产品详细信息的下一页。如果用户决定向后导航,则页面不会滚动到上一个点。

4 个答案:

答案 0 :(得分:13)

尝试在状态下处理滚动位置更改:

<FlatList onScroll={this.handleScroll} />

handleScroll 方法:

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

然后您可以在导航回来时使用 scrollToOffset(this.state.scrollPosition)

答案 1 :(得分:1)

我使用react-navigation在FlatList和详细信息视图之间导航。我也使用react-redux来跟踪状态。这是我所遵循的过程。

  • 基本上侦听导航器的更改并将redux保存为当前路径的名称
  • 当您在FlatList中选择一个项目时,请记住您选择的项目的索引
  • 当您返回FlatList时,计算该索引的偏移并滚动

表示完成起来有点容易然后在我自己的Component中,我的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}
       />
    )
}

答案 2 :(得分:0)

对于任何使用功能组件的人来说,这都会有所帮助。

第 1 步:使用钩子创建一个常量以保持滚动位置的初始值为零。

  const [scrollPosition,setScrollPosition]=React.useState(0)

第 2 步:创建更新滚动位置的方法。当用户滚动时。

const handleScroll=(event)=>{
  let yOffset=event.nativeEvent.contentOffset.y / heightOfYourListItem;
  setScrollPosition(yOffset)
}

第 3 步:当用户滚动平面列表时调用 handleScroll() 方法。

    <FlatList
            enableEmptySections={true}
            onScroll={(event)=>handleScroll(event)}
            initialScrollIndex={scrollPosition}
            numColumns={2}
            keyExtractor={(item) => item.Id}
            data={Items}
            renderItem={({item}) =>renderListItems(item}
/>

答案 3 :(得分:-2)

在Flatlist set scrollsToTop={false}中,当您从详细信息屏幕导航回来时,这将保留位置。我正在使用Expo 25版。