javascript 在 react native 中导航回时如何使用 flatlist 保持滚动位置?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/48061234/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to keep scroll position using flatlist when navigating back in react native ?
提问by Pulkit Aggarwal
I am new to react native. I am facing problem in maintaining the position of flatlist when navigating forward and then come back to that screen.
我是本机反应的新手。在向前导航然后返回到该屏幕时,我在保持 flatlist 的位置时遇到了问题。
Current behavior
When navigating forward and then back, the scroll position is lost.
当前行为
向前和向后导航时,滚动位置丢失。
Expected behavior
When navigating on an extensive list of items, the user scrolls down the list and click on some item. The app goes to the next page which shows the product details. If the user decides do navigate back, the page does not scroll to the previous point.
预期行为
在广泛的项目列表上导航时,用户向下滚动列表并单击某个项目。该应用程序转到显示产品详细信息的下一页。如果用户决定向后导航,页面不会滚动到上一点。
回答by Marcos Demétrio
Try handling scroll position changing on a state:
尝试处理更改状态的滚动位置:
<FlatList onScroll={this.handleScroll} />
handleScrollmethod:
处理滚动方法:
handleScroll: function(event: Object) {
this.setState({ scrollPosition: event.nativeEvent.contentOffset.y });
}
Then you can use scrollToOffset(this.state.scrollPosition)when you navigate back.
然后您可以在返回时使用scrollToOffset(this.state.scrollPosition)。
If you use react-navigation and want to keep the scroll position after navigation, try this hack:
如果您使用 react-navigation 并希望在导航后保持滚动位置,请尝试以下技巧:
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)
})
}
回答by Kerkness
I'm using react-navigation to navigate between a FlatList and a details view. I'm also using react-redux to track state. Here's the process I've followed.
我正在使用 react-navigation 在 FlatList 和详细信息视图之间导航。我也在使用 react-redux 来跟踪状态。这是我遵循的过程。
- Basically listen for changes to the navigator and save in redux the name of the current route
- When you select an item in your FlatList remember the index of the item you selected
- When you return to your FlatList calculate the offset for that index and scroll
- 基本上监听导航器的变化并将当前路由的名称保存在 redux 中
- 当您在 FlatList 中选择一个项目时,请记住您选择的项目的索引
- 当您返回 FlatList 时,计算该索引的偏移量并滚动
That's all a little easier said then done and in my own Component the rows in my FlatList are variable so that complicates calculating the offset but heres an example assuming your rows are the same
这一切说起来容易一点,然后做起来容易一些,在我自己的组件中,我的 FlatList 中的行是可变的,因此计算偏移量很复杂,但这里有一个假设您的行相同的示例
My App component which renders the navigator
呈现导航器的我的 App 组件
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} />
My component with the FlatList looks like this
我的带有 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}
/>
)
}
回答by bamne123
In Flatlist set scrollsToTop={false}this will retain position when you navigate back from detail screen. I am using Expo version 25.
在 Flatlist 设置中,scrollsToTop={false}当您从详细信息屏幕导航回来时,这将保留位置。我正在使用 Expo 版本 25。

