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)
})
}
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}
/>
)
}
6条答案
按热度按时间iaqfqrcu1#
尝试在以下状态下处理滚动位置更改:
handleScroll方法:
然后,您可以在向后导航时使用scrollToOffset(this.state.scrollPosition)。
如果你使用React导航,并希望保持导航后的滚动位置,试试这个黑客:
fbcarpbf2#
我使用react-navigation在FlatList和细节视图之间导航,还使用react-redux跟踪状态。
这一切说起来容易做起来难,在我自己的Component中,FlatList中的行是可变的,因此计算偏移量变得复杂,但这里是一个假设行相同的示例
呈现导航器的My App组件
我的FlatList组件如下所示
4si2a6ki3#
react-navigation的当前行为实际上是当你在屏幕之间来回切换时,滚动位置被记住。当你从一个
headerTransparent
设置为与你导航状态不同的设置的屏幕切换时,它确实重置。thigvfpy4#
为了避免使用setState进行多次重新渲染,而不是使用多次调用的onScroll,你可以使用这两个 prop 来涵盖这两种情况。第一种情况是用户拖动并停止触摸屏幕,第二种情况是用户通过拖动到达该点。总共你只有2次重新渲染,而不是20-50次或其他。
zphenhs45#
对于任何使用功能组件的人来说,这将是有帮助的。
第一步:使用钩子创建一个常量来保持滚动位置,初始值为零。
第二步:创建一个更新滚动位置的方法。当用户滚动时。
步骤3:当用户滚动平面列表时调用handleScroll()方法。
44u64gxh6#
在平面列表集合
scrollsToTop={false}
中,当你从细节屏幕导航回来时,这将保留位置。我使用的是Expo版本25。