我能够通过 onMoveShouldSetPanResponder 方法完成此操作,如下所示:
onMoveShouldSetPanResponder: (evt, gestureState) => {
return Math.abs(gestureState.dx) >= 1 || Math.abs(gestureState.dy) >= 1
}
如果 x 或 y 移动大于 1,则返回 true。然后为了检测点击,我必须将包含 panHandlers 的所有内容都包含在我的视图中,并带有一个可触摸的元素。这是一个完整的工作示例:
import React, { Component } from 'react';
import { TouchableOpacity, Animated, PanResponder, Text, View, StyleSheet } from 'react-native';
import Constants from 'expo-constants';
export default function App() {
return (
<View>
<CircleTapExample/>
</View>
);
}
class CircleTapExample extends Component {
constructor(props) {
super(props)
this.position = new Animated.ValueXY({ x: 0, y: 0 });
this.panResponder = PanResponder.create({
onMoveShouldSetPanResponder: (evt, gestureState) => {
return Math.abs(gestureState.dx) >= 1 || Math.abs(gestureState.dy) >= 1
},
onPanResponderMove: (evt, gestureState) => {
console.log("I was moved")
this.position.setValue({ x: gestureState.moveX, y: gestureState.moveY })
},
});
}
circleTapped() {
// Do something here when tapped
console.log("I was tapped")
}
render() {
return (
<Animated.View style={[styles.container, { ...this.position.getLayout() }]} {...this.panResponder.panHandlers}>
<TouchableOpacity onPress={() => this.circleTapped()} style={{ flex: 1 }}>
<View style={styles.circle} />
</TouchableOpacity>
</Animated.View>
)
}
}
const styles = StyleSheet.create({
container: {
width: 75,
height: 75,
bottom: 5,
left: 5,
position: 'absolute'
},
circle: {
width: 75,
height: 75,
borderRadius: 40,
backgroundColor: 'red'
}
});
<div data-snack-id="YskU-lxRe" data-snack-platform="web" data-snack-preview="true" data-snack-theme="light" style="overflow:hidden;background:#F9F9F9;border:1px solid var(--color-border);border-radius:4px;height:505px;width:100%"></div>
<script async src="https://snack.expo.dev/embed.js"></script>