[英]React-native: scrollview inside of panResponder
我在 PanResponder 中使用了 ScrollView。 在 Android 上它工作正常,但在 iOS 上 ScrollView 不會滾動。 我做了一些調查,這里有一些事實:
如果我在PanResponder.onMoveShouldSetPanResponder()
放置一個斷點,在我跨過去之前,scrollView 將正常滾動,但是一旦我釋放斷點,scrollView 就會停止工作。
如果我修改 ScrollResponder.js,並在scrollResponderHandleStartShouldSetResponderCapture()
返回 true - 它曾經在運行時返回 false; 並在scrollResponderHandleTerminationRequest()
返回 false ,scrollView 工作正常,但當然,因為它吞下了事件,外部PanResponder
將不會獲得該事件。
所以問題是:
我最終通過將滾動視圖包裹在視圖中來解決這個問題,並將滾動視圖的樣式設置為有限的高度。
import * as React from 'react';
import { Text, View, StyleSheet,PanResponder,Animated,ScrollView,Dimensions} from 'react-native';
import { Constants } from 'expo';
const WINDOW_WIDTH = Dimensions.get("window").width;
const WINDOW_HEIGHT = Dimensions.get("window").height;
// You can import from local files
export default class App extends React.Component {
constructor(props){
super(props);
this.minTop = 100;
this.maxTop = 500;
this.state={
AnimatedTop:new Animated.Value(0),
}
}
componentWillMount(){
let that = this;
this._previousTop = 100;
this._panResponder = PanResponder.create({
onMoveShouldSetPanResponder(){
return true;
},
onPanResponderGrant(){
that._previousTop = that.state.AnimatedTop.__getValue();
return true;
},
onPanResponderMove(evt,gestureState){
let currentTop = that._previousTop + gestureState.dy;
that.state.AnimatedTop.setValue(that._previousTop+gestureState.dy);
},
onPanResponderRelease(){
}
})
}
render() {
return (
<View style={styles.container}>
<Animated.View
style={[styles.overlay,{top:this.state.AnimatedTop}]}
{...this._panResponder.panHandlers}
>
<View style={{height:200,backgroundColor:"black"}}></View>
<View>
<ScrollView
style={{height:500}}
>
<View style={{backgroundColor:"blue",height:200}}></View>
<View style={{backgroundColor:"yellow",height:200}}></View>
<View style={{backgroundColor:"pink",height:200}}></View>
<View style={{backgroundColor:"red",height:200}}></View>
</ScrollView>
</View>
</Animated.View>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
paddingTop: Constants.statusBarHeight,
backgroundColor: '#ecf0f1',
padding: 8,
},
overlay:{
position:"absolute",
width:WINDOW_WIDTH,
height:WINDOW_HEIGHT-100,
}
});
在這里輸入鏈接描述我花了很多時間來解決這個問題。希望這會幫助那些對同樣問題感到困惑的人。
PanResponder 中有一個返回當前觸摸位置的事件。 您可以使用它來比較 2 個值以執行滾動。
我不知道它現在是否有用,但您可以添加該行,
return !(gestureState.dx === 0 && gestureState.dy === 0)
在 PanResponder 的 'onMoveShouldSetPanResponder' 屬性中,以 evt 和gestureState 作為參數。
您的 PanResponder 應如下所示:
this._panResponder = PanResponder.create({
onMoveShouldSetPanResponder(evt, gestureState){
return !(gestureState.dx === 0 && gestureState.dy === 0)
},
onPanResponderGrant(){
that._previousTop = that.state.AnimatedTop.__getValue();
return true;
},
onPanResponderMove(evt,gestureState){
let currentTop = that._previousTop + gestureState.dy;
that.state.AnimatedTop.setValue(that._previousTop+gestureState.dy);
},
onPanResponderRelease(){
}
})
我已經通過向 ScrollView 的所有內容添加onPress
處理程序解決了這個問題 - 如果處理程序是無操作的,滾動視圖仍然可以正常工作。
我通過這樣做解決了這個問題
onMoveShouldSetPanResponder: (event, gesture) => {
if (gesture?.moveX > gesture?.moveY) {
return false;
}
return true;
},
就我而言,我在 PanResponder 中有一個水平 Flatlist ......
要在具有 PanResponder 的父級的子級 ScrollView 中啟用滾動,您必須確保 ScrollView 是其中任何手勢的響應者。 默認情況下,手勢事件從最深的組件冒泡到父組件。 為了通過 ScrollView 捕獲事件,您可以添加一個內部帶有 PanResponder 的視圖。 請參閱下面的(偽)示例,其中ChildComponent
是具有 PanResponder 的父級的子級。
const ChildComponent = ({ theme }) => {
const panResponder = React.useRef(
PanResponder.create({
// Ask to be the responder:
onStartShouldSetPanResponder: (evt, gestureState) => true,
onStartShouldSetPanResponderCapture: (evt, gestureState) => true,
})
).current;
return (
<ScrollView style={{ height: 500 }}>
<View {...panResponder.panHandlers}>
...
</View>
</ScrollView>
);
};
我不確定你是否還需要這個,但我也會幫助別人
如果將 panResponder 放在 ScrollView 的同級視圖上,則 ScrollView 的行為正常。 然后您可以定位該兄弟視圖
這是解決方法的示例。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.