这是关于(我要实现的)质量降低的GIF。
我有一个scrollview
,它位于屏幕的一半。
我想要的是将scrollview
向上拖动,然后在到达某个位置时将drag touch event
发送到scrollview
本身,以便它可以继续滚动。
contentContainerStyle
上添加一个半屏填充。效果很好,但是我无法单击它后面的视图。有没有办法点击滚动视图的空白区域?我还尝试检测滚动位置,以便相应地向上移动视图
<ScrollView onScroll={event => moveScrollViewUpIfNeeded(event)}>
...
</ScrollView>
,但是当我在iOS模拟器上对其进行测试时无法正常工作。事件甚至没有触发。 React Native Docs指出onScroll
需要scrollEventThrottle
才能工作。但是,scrollEventThrottle
仅是available on iOS。就我而言,我也想在Android上使用它。
而且,如果我成功实现了这一点,我将面临另一个UI问题:向上拖动ScrollView时,如何在视图尚未到达所需位置时阻止它滚动?
那么,请您给我一些技巧来实现这一目标:)?
谢谢
答案 0 :(得分:7)
我尝试了几种选择。这是我的性能最佳的解决方案。当然,这只是一个可行的示例,您可能需要进一步优化它以完全满足您的需求。
基本思想是将地图始终保持在叠加层的背景中。叠加层是绝对定位的,包含两个视图。一个视图是透明的,我们仍然可以在其中查看和控制地图,另一个视图包含实际的ScrollView。诀窍是设置父叠加层的pointerEvents="box-none"
,并在要与地图进行交互的View的pointerEvents="none"
中禁用指标事件。
基本渲染方法:
<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,则希望缩小空的View,以便ScrollView变为全屏。因此,我们收听ScrollView的onScroll
方法。参见下面的代码和注释:
_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
道具,我们可以控制_onScroll
方法的调用频率。 (在这里您可能需要微调)
答案 1 :(得分:0)
我认为最好将MapView和BottomView都放在一个ScrollView
中。
它将保存自然的滚动行为,并防止诸如向下滚动时出现白色条纹或向上滚动时消失的副作用。这里的主要问题是如何为MapView
设置“冻结”效果。
通过将MapView
容器内的Animated
相对于滚动事件进行转换,可以使用视差效果。我认为Animated library和Animatable components将是解决此类问题的好方法:
scroll = new Animated.Value(0)
render() {
return <Animated.ScrollView ...
onScroll={Animated.event([{nativeEvent: {contentOffset: {y: this.scroll}}}], {useNativeDriver: true})}>
<Animated.View
style={
{ ...transform:
[{translateY: Animated.multiply(this.scroll, 0.8)}]}}>
<MapView />
</Animated.View>
<BottomView />
</Animated.ScrollView>
}
实际上,如果您不希望有视差效果,可以将Animated.multiply(this.scroll, 0.8)
替换为this.scroll
您可以在此处看到完整的示例:Code example