背景
在使用scrollview或者listview時买雾,一般有兩種情況會出現(xiàn)手勢沖突
- scrollview在一個touch的內(nèi)部
- scrollview包裹一個touch
上面我們只考慮了一個scrollview和一個touch的情況,而多個scrollview和多個touch的情況可以進行類比。
當一個scrollview包裹一個touch時抠刺,造成的沖突一般是touch響應(yīng)時scrollview也會有響應(yīng)敏沉,這時禁止scrollview的滾動即可,下面我們將說明一下如何解決scrollview在一個touch內(nèi)部造成的手勢沖突
問題
當一個scrollview在一個touch內(nèi)部時,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都沒有響應(yīng),為父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
}
});