我尝试了几种选择。这是我的解决方案,在性能方面效果最好。当然这只是一个工作示例,您可能需要进一步优化它以完全满足您的需求。
演示:
解释:
基本思想是将地图始终保持在叠加层的背景中。叠加层是绝对定位的并包含两个视图。一个 View 是透明的,我们仍然可以看到和控制地图,另一个 View 包含实际的 ScrollView。诀窍是设置pointerEvents="box-none"
父叠加层并禁用pointerEvents="none"
我们想要与地图交互的 View 的 pointerEvents。
基本渲染方法:
<SafeAreaView style={{flex: 1}}>
<MapView
initialRegion={region}
style={{height: HEIGHT, width: WIDTH}}
/>
<View pointerEvents="box-none"style={{height: HEIGHT, width: WIDTH, position: 'absolute'}}>
<View pointerEvents="none" style={{height: this.state.height, backgroundColor: 'transparent'}} />
<View style={{ height: HEIGHT-this.state.height, backgroundColor: 'white'}}>
<ScrollView onScroll={(e) => this._onScroll(e)} scrollEventThrottle={10} >
-- content of scrollview goes here ---
</ScrollView>
</View>
</View>
</SafeAreaView>
滚动功能:
如果我们向下滚动 ScrollView,我们想要缩小空视图,使 ScrollView 变为全屏。因此我们监听onScroll
ScrollView的方法。请参阅下面的代码和注释:
_onScroll(e){
// from the nativeEvent we can get the contentOffsett
var offset_y = e.nativeEvent.contentOffset.y;
if (offset_y > 0 ) {
if (this.state.height>=0){
// we are scrolling down the list, decrease height of the empty view
this.setState({height: this.state.height-offset_y});
}
}
if (offset_y <0){
if (this.state.height <= this.state.mapHeight){
// we are scrolling up the list, increase size of empty view/map view
this.setState({height: this.state.height-offset_y});
}
}
}
使用 ScrollView 的scrollEventThrottle
prop,我们可以控制_onScroll
调用该方法的频率。(这里你可能需要微调)
完整的代码和工作零食
https://snack.expo.io/@tim1717/rnmapwithoverlay