react-native - 屏幕上的多个 panresponder 管理不同的区域(同时)
问题描述
有什么办法可以同时使用两个 Panresponder 而不会相互干扰?
我想创建一个应用程序,可以在特定区域同时更改两个样方的位置:蓝色样方应该只能在蓝色区域中移动,而灰色样方应该只能在白色区域中移动。(图片:在这里你可以看到我的应用程序屏幕)但问题是触摸事件相互干扰。
到目前为止,这是我的代码:
import React, { useState } from "react";
import {
StyleSheet,
Text,
View,
Animated,
PanResponder,
Dimensions,
} from "react-native";
const phoneWidth = Dimensions.get("window").width;
export default function App() {
const ball = useState(new Animated.ValueXY())[0];
const panResponder = useState(
new PanResponder.create({
onStartShouldSetPanResponder: () => false,
onMoveShouldSetPanResponder: () => true,
onPanResponderGrant: (_, gesture) => {
ball.setOffset({
x: ball.x._value,
y: ball.y._value,
});
},
onPanResponderMove: (_, gesture) => {
console.log(gesture);
if (gesture.moveY < 200) {
ball.x.setValue(gesture.dx);
ball.y.setValue(gesture.dy);
}
},
onPanResponderRelease: () => {
ball.flattenOffset();
if (ball.y._value > 160) {
ball.y.setValue(160);
}
if (ball.y._value < 0) {
ball.y.setValue(0);
}
ball.flattenOffset();
if (ball.x._value > phoneWidth - 50) {
ball.x.setValue(phoneWidth - 50);
}
if (ball.x._value < 0) {
ball.x.setValue(0);
}
},
})
)[0];
const ball2 = useState(new Animated.ValueXY())[0];
const panResponder2 = useState(
new PanResponder.create({
onStartShouldSetPanResponder: () => false,
onMoveShouldSetPanResponder: () => true,
onPanResponderGrant: () => {
ball2.setOffset({
x: ball2.x._value,
y: ball2.y._value,
});
},
onPanResponderMove: (_, gesture) => {
ball2.x.setValue(gesture.dx);
ball2.y.setValue(gesture.dy);
},
onPanResponderRelease: () => {
ball2.flattenOffset();
},
})
)[0];
return (
<View style={styles.container}>
<View style={styles.whitefield}>
<Animated.View
style={[styles.grayBall, ball.getLayout()]}
{...panResponder.panHandlers}
/>
</View>
<View style={styles.bluefield}>
<Animated.View
style={[styles.blueball, ball2.getLayout()]}
{...panResponder2.panHandlers}
/>
</View>
</View>
);
}
const styles = StyleSheet.create({
whitefield: {
position: "absolute",
top: 0,
left: 0,
height: 200,
width: 400,
backgroundColor: "white",
},
bluefield: {
position: "absolute",
top: Dimensions.get("window").height - 200,
left: 0,
height: 200,
width: 400,
backgroundColor: "lightskyblue",
},
container: {
flex: 1,
backgroundColor: "yellow",
alignItems: "center",
justifyContent: "center",
},
blueball: {
width: 50,
height: 50,
backgroundColor: "blue",
},
grayBall: {
width: 50,
height: 50,
backgroundColor: "grey",
},
});
解决方案
这不是一个完整的答案,但作为评论已经太多了:
我不知道如何使视图的平移处理程序不冒泡;(因为我无法阻止处理程序从第二次触摸(即来自不同的视图)运行。我想我将尝试创建自己的版本dx, dy, dx2, dy2 来自被调用的处理程序。大技巧将尝试使用event.nativeEvent.touches
哪个是从 in 调用的屏幕上的活动触摸数组onPanResponderMove
onPanResponderMove: Animated.event(
[
null,
{ dx: this.pan2.x, dy: this.pan2.y }
],
{
useNativeDriver: false,
listener: (event, gestureState) => {
let touches = event.nativeEvent.touches;
//do stuff here
}
}
)
推荐阅读
- angular - Angular 12.x,将根组件拆分为自己的包
- node.js - 如何更新 MongoDB 中特定记录的特定键
- python - 使用 Kivy 滚动异步图像网格
- webpack - 属性选择器在生产环境中不能与 webpack 一起使用
- spring - Hibernate 异常:找到了不止一行具有给定标识符的行
- flutter - PageView 页面未释放,应用程序内存不足并崩溃
- mkdocs - 如何在 MKDocs 正文中“嵌入”自定义 404 页面?
- kotlin - 如何使用不同数据类的属性更新 kotlin 数据类
- arrays - 用于二维数组和按位运算的 C 到 MIPS 转换
- mysql - 如何通过最小值和最大值之间的计数获得最多 20 个组