![](/img/trans.png)
[英]React Native - How to refresh FlatList when back to previous page?
[英]How to keep scroll position using flatlist when navigating back in react native ?
我是新来的本地人。 向前导航然后返回到该屏幕时,我在保持平面列表的位置时遇到问题。
当前行为
向前导航然后向后导航时,滚动位置会丢失。
预期行为
当浏览大量项目列表时,用户向下滚动列表并单击某个项目。 该应用程序会转到显示产品详细信息的下一页。 如果用户决定向后导航,则页面不会滚动到前一点。
尝试处理更改状态的滚动位置:
<FlatList onScroll={this.handleScroll} />
处理滚动方法:
handleScroll: function(event: Object) {
this.setState({ scrollPosition: event.nativeEvent.contentOffset.y });
}
然后您可以在返回时使用scrollToOffset(this.state.scrollPosition) 。
如果您使用 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)
})
}
我正在使用 react-navigation 在 FlatList 和详细信息视图之间导航。 我也在使用 react-redux 来跟踪状态。 这是我遵循的过程。
这一切说起来容易一点,然后做起来容易一些,在我自己的组件中,我的 FlatList 中的行是可变的,因此计算偏移量很复杂,但这里有一个假设您的行相同的示例
呈现导航器的我的 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} />
我的带有 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}
/>
)
}
对于任何使用功能组件的人来说,这将是有帮助的。
第 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}
/>
react-navigation 的当前行为实际上是在屏幕之间来回切换时记住滚动位置。 但是,当您从将headerTransparent
设置为与您从那里导航的状态不同的设置的屏幕切换时,它确实会重置。
为了避免使用 setState 多次重新渲染,而不是多次调用的 onScroll,您可以使用这两个 props 来涵盖这两种情况。 第一种情况是用户拖动并停止触摸屏幕,第二种情况是用户通过拖动到达该点。 总的来说,您只有 2 次重新渲染,而不是 20-50 次或其他。
onMomentumScrollEnd={e => setScrollPos(e.nativeEvent.contentOffset.y)}
onScrollEndDrag={e => setScrollPos(e.nativeEvent.contentOffset.y)}
在 Flatlist 中设置scrollsToTop={false}
这将在您从详细信息屏幕返回时保留位置。 我正在使用 Expo 版本 25。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.