背景
在使用scrollview或者listview时,一般有两种情况会出现手势冲突
- scrollview在一个touch的内部
- scrollview包裹一个touch
上面我们只考虑了一个scrollview和一个touch的情况,而多个scrollview和多个touch的情况可以进行类比。
当一个scrollview包裹一个touch时,造成的冲突一般是touch响应时scrollview也会有响应,这时禁止scrollview的滚动即可,下面我们将说明一下如何解决scrollview在一个touch内部造成的手势冲突
问题
当一个scrollview在一个touch内部时,scrollview将得不到任何事件(android上可能好一点儿),示例代码如下:
export default class scrollPan extends Component {
constructor(props){
super(props);
this.wrapperPanResponder = PanResponder.create({
onStartShouldSetPanResponder: (e, g) => true,
onPanResponderGrant: () => {
console.log('GRANTED TO WRAPPER');
},
onPanResponderMove: (evt, gestureState) => {
console.log('WRAPPER MOVED');
}
});
this.scollerPanResponder = PanResponder.create({
onStartShouldSetPanResponder: (e, g) => true,
onPanResponderGrant: () => {
console.log('GRANTED TO SCROLLER');
},
onPanResponderMove: (evt, gestureState) => {
console.log('SCROLLER MOVED');
}
});
}
render() {
return (
<View style={styles.container} {...this.wrapperPanResponder.panHandlers}>
<ScrollView onScroll={() => console.log('scrolled')} style={{maxHeight: 350}} {...this.scollerPanResponder.panHandlers}>
<Text style={{fontSize:96}}>Scroll this</Text>
<Text style={{fontSize:96}}>Scroll this</Text>
<Text style={{fontSize:96}}>Scroll this</Text>
<Text style={{fontSize:96}}>Scroll this</Text>
<Text style={{fontSize:96}}>Scroll this</Text>
</ScrollView>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
});
运行代码后,点击与滑动scrollview都没有响应,为父touch加上手势放行或者只拦截点击事件,不拦截move事件也解决不了问题
解决办法
将panResonder改为绝对布局,即可解决冲突
export default class scrollPan extends Component {
constructor(props){
super(props);
this.wrapperPanResponder = PanResponder.create({
onStartShouldSetPanResponder: (e, g) => true,
onPanResponderGrant: () => {
console.log('GRANTED TO WRAPPER');
},
onPanResponderMove: (evt, gestureState) => {
console.log('WRAPPER MOVED');
}
});
this.scollerPanResponder = PanResponder.create({
onStartShouldSetPanResponder: (e, g) => true,
onPanResponderGrant: () => {
console.log('GRANTED TO SCROLLER');
},
onPanResponderMove: (evt, gestureState) => {
console.log('SCROLLER MOVED');
}
});
}
render() {
return (
<View style={styles.container}>
<View style={styles.pan_container} {...this.wrapperPanResponder.panHandlers} />
<ScrollView onScroll={() => console.log('scrolled')} style={styles.scroll_view} {...this.scollerPanResponder.panHandlers}>
<Text style={{fontSize:96}}>Scroll this</Text>
<Text style={{fontSize:96}}>Scroll this</Text>
<Text style={{fontSize:96}}>Scroll this</Text>
<Text style={{fontSize:96}}>Scroll this</Text>
<Text style={{fontSize:96}}>Scroll this</Text>
</ScrollView>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
pan_container: {
...StyleSheet.absoluteFillObject,
backgroundColor: 'blue'
},
scroll_view: {
backgroundColor: 'teal',
maxHeight: 350
}
});
网友评论