我有一个组件需要执行如下操作:当用户点击或拖动它时,我需要它转到其他元素的顶部。为此,我使用 PanGestureHandler 和 TapGestureHandler 将内容包装在一起,如下所示:
<PanGestureHandler
ref={panRef}
onGestureEvent={onGestureEvent}
onHandlerStateChange={onHandlerStateChange}
simultaneousHandlers={tapRef}>
<Animated.View
style={[
styles.panGestureView,
{
transform: [
{translateX: translateX.current},
{translateY: translateY.current},
],
},
{position: 'absolute'},
]}>
<TapGestureHandler
ref={tapRef}
onHandlerStateChange={onTapHandlerStateChange}
simultaneousHandlers={panRef}>
<View>{children}</View>
</TapGestureHandler>
</Animated.View>
</PanGestureHandler>
问题是:在点击处理程序中,当我重新排列组件数组以将此组件放在所有其他组件之上时,PanGesture 不会调用处理程序,因此用户无法再拖动此组件。只有当他再次按下时,它才会起作用。
但是,如果我在点击处理程序上做相反的事情(而不是将元素放在顶部,但低于其他元素)它工作得很好。
处理程序:
const onGestureEvent = Animated.event(
[
{
nativeEvent: {
translationX: translateX.current,
translationY: translateY.current,
},
},
],
{useNativeDriver: true},
);
const onHandlerStateChange = (event) => {
if (event.nativeEvent.oldState === State.ACTIVE) {
lastOffset.current.x += event.nativeEvent.translationX;
lastOffset.current.y += event.nativeEvent.translationY;
translateX.current.setOffset(lastOffset.current.x);
translateX.current.setValue(0);
translateY.current.setOffset(lastOffset.current.y);
translateY.current.setValue(0);
}
};
const onTapHandlerStateChange = (event) => {
setActiveElement(element);
const newElementsArray = elements.filter(
(item) => item.elementId !== element.elementId,
);
setElements([...newElementsArray, element]);
};
如何将组件放在它上面并能够保持拖动事件?