From cfe811ab18ec98776d2564de527544d45813508f Mon Sep 17 00:00:00 2001 From: Luna Wei Date: Tue, 1 Nov 2022 12:50:05 -0700 Subject: [PATCH] Fix natively driven animated.event for bubbling PointerEvents Summary: Changelog: [Internal] Override logic for determining whether a dispatched `Event` triggers a native `EventAnimationDriver`. Natively driven AnimatedEvents on bubbling events is not supported. `PointerEvents` requires this and this diff adds custom matching logic such that if a parent specifies an `AnimatedEvent` on `onPointerMove` and a child view dispatches it, the `AnimatedEvent` will still fire. Reviewed By: javache Differential Revision: D38722563 fbshipit-source-id: 7cde57eaff9584b33c6ab15f1fe85c0a9bac132e --- .../react/uimanager/events/PointerEvent.java | 30 +++++++++++++++++++ .../uimanager/events/PointerEventHelper.java | 14 +++++++++ 2 files changed, 44 insertions(+) diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/PointerEvent.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/PointerEvent.java index e7e69919f91..ed7004a1fc9 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/PointerEvent.java +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/PointerEvent.java @@ -66,6 +66,7 @@ public class PointerEvent extends Event { private short mCoalescingKey = UNSET_COALESCING_KEY; private @Nullable List mPointersEventData; private PointerEventState mEventState; + private @Nullable Event.EventAnimationDriverMatchSpec mEventAnimationDriverMatchSpec; private void init( String eventName, @@ -114,6 +115,31 @@ public class PointerEvent extends Event { return; } + @Override + public Event.EventAnimationDriverMatchSpec getEventAnimationDriverMatchSpec() { + if (mEventAnimationDriverMatchSpec == null) { + mEventAnimationDriverMatchSpec = + new EventAnimationDriverMatchSpec() { + @Override + public boolean match(int viewTag, String eventName) { + if (!PointerEventHelper.isBubblingEvent(eventName)) { + return false; + } + + List viewTargets = + mEventState.getHitPathForActivePointer(); + for (TouchTargetHelper.ViewTarget viewTarget : viewTargets) { + if (viewTarget.getViewId() == viewTag && eventName.equals(mEventName)) { + return true; + } + } + return false; + } + }; + } + return mEventAnimationDriverMatchSpec; + } + @Override public void onDispose() { mPointersEventData = null; @@ -329,5 +355,9 @@ public class PointerEvent extends Event { public final Map getEventCoordinatesByPointerId() { return mEventCoordinatesByPointerId; } + + public final List getHitPathForActivePointer() { + return mHitPathByPointerId.get(mActivePointerId); + } } } diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/PointerEventHelper.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/PointerEventHelper.java index 8e1873ed94c..da6b77cd1a2 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/PointerEventHelper.java +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/PointerEventHelper.java @@ -212,4 +212,18 @@ public class PointerEventHelper { boolean inActiveButtonState = buttonState != 0; return inActiveButtonState ? 0.5 : 0; } + + public static boolean isBubblingEvent(String eventName) { + switch (eventName) { + case POINTER_UP: + case POINTER_DOWN: + case POINTER_OVER: + case POINTER_OUT: + case POINTER_MOVE: + case POINTER_CANCEL: + return true; + default: + return false; + } + } }