Skip to content

Commit dc2d57b

Browse files
authored
Merge branch 'next' into @latekvo/remove-paper-support-new
2 parents b396263 + 02e1317 commit dc2d57b

44 files changed

Lines changed: 563 additions & 229 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

apps/basic-example/src/NativeDetector.tsx

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,7 @@ export default function App() {
1818
);
1919

2020
const gesture = useGesture('PanGestureHandler', {
21-
onGestureHandlerAnimatedEvent: event,
22-
onGestureHandlerEvent: (e: any) =>
23-
console.log('onGestureHandlerEvent', e.nativeEvent),
21+
onUpdate: event,
2422
});
2523

2624
return (

packages/react-native-gesture-handler/android/src/main/java/com/swmansion/gesturehandler/core/GestureHandler.kt

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import com.facebook.react.bridge.WritableArray
1818
import com.facebook.react.uimanager.PixelUtil
1919
import com.swmansion.gesturehandler.BuildConfig
2020
import com.swmansion.gesturehandler.RNSVGHitTester
21+
import com.swmansion.gesturehandler.react.RNGestureHandlerDetectorView
2122
import com.swmansion.gesturehandler.react.RNGestureHandlerTouchEvent
2223
import com.swmansion.gesturehandler.react.eventbuilders.GestureHandlerEventDataBuilder
2324
import java.lang.IllegalStateException
@@ -30,6 +31,22 @@ open class GestureHandler {
3031
var tag = 0
3132
var view: View? = null
3233
private set
34+
val viewForEvents: RNGestureHandlerDetectorView
35+
get() {
36+
assert(actionType == ACTION_TYPE_NATIVE_DETECTOR) {
37+
"[react-native-gesture-handler] `viewForEvents` can only be used with NativeDetector."
38+
}
39+
40+
val detector = if (this is NativeViewGestureHandler) this.view?.parent else view
41+
42+
if (detector !is RNGestureHandlerDetectorView) {
43+
throw Error(
44+
"[react-native-gesture-handler] Expected RNGestureHandlerDetectorView to be the target for the event.",
45+
)
46+
}
47+
48+
return detector
49+
}
3350
var state = STATE_UNDETERMINED
3451
private set
3552
var x = 0f
@@ -62,6 +79,7 @@ open class GestureHandler {
6279
private set
6380
private val trackedPointers: Array<PointerData?> = Array(MAX_POINTERS_COUNT) { null }
6481
var needsPointerData = false
82+
var dispatchesAnimatedEvents = false
6583

6684
private var hitSlop: FloatArray? = null
6785
var eventCoalescingKey: Short = 0
@@ -822,6 +840,8 @@ open class GestureHandler {
822840
}
823841
}
824842

843+
open fun wantsToAttachDirectlyToView() = false
844+
825845
override fun toString(): String {
826846
val viewString = if (view == null) null else view!!.javaClass.simpleName
827847
return this.javaClass.simpleName + "@[" + tag + "]:" + viewString
@@ -859,6 +879,9 @@ open class GestureHandler {
859879
if (config.hasKey(KEY_NEEDS_POINTER_DATA)) {
860880
handler.needsPointerData = config.getBoolean(KEY_NEEDS_POINTER_DATA)
861881
}
882+
if (config.hasKey(KEY_DISPATCHES_ANIMATED_EVENTS)) {
883+
handler.dispatchesAnimatedEvents = config.getBoolean(KEY_DISPATCHES_ANIMATED_EVENTS)
884+
}
862885
if (config.hasKey(KEY_MANUAL_ACTIVATION)) {
863886
handler.manualActivation = config.getBoolean(KEY_MANUAL_ACTIVATION)
864887
}
@@ -873,6 +896,7 @@ open class GestureHandler {
873896
private const val KEY_SHOULD_CANCEL_WHEN_OUTSIDE = "shouldCancelWhenOutside"
874897
private const val KEY_ENABLED = "enabled"
875898
private const val KEY_NEEDS_POINTER_DATA = "needsPointerData"
899+
private const val KEY_DISPATCHES_ANIMATED_EVENTS = "dispatchesAnimatedEvents"
876900
private const val KEY_MANUAL_ACTIVATION = "manualActivation"
877901
private const val KEY_MOUSE_BUTTON = "mouseButton"
878902
private const val KEY_HIT_SLOP = "hitSlop"
@@ -968,7 +992,6 @@ open class GestureHandler {
968992
const val ACTION_TYPE_JS_FUNCTION_OLD_API = 3
969993
const val ACTION_TYPE_JS_FUNCTION_NEW_API = 4
970994
const val ACTION_TYPE_NATIVE_DETECTOR = 5
971-
const val ACTION_TYPE_NATIVE_DETECTOR_ANIMATED_EVENT = 6
972995
const val POINTER_TYPE_TOUCH = 0
973996
const val POINTER_TYPE_STYLUS = 1
974997
const val POINTER_TYPE_MOUSE = 2

packages/react-native-gesture-handler/android/src/main/java/com/swmansion/gesturehandler/core/NativeViewGestureHandler.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,8 @@ class NativeViewGestureHandler : GestureHandler() {
167167
this.hook = defaultHook
168168
}
169169

170+
override fun wantsToAttachDirectlyToView() = true
171+
170172
class Factory : GestureHandler.Factory<NativeViewGestureHandler>() {
171173
override val type = NativeViewGestureHandler::class.java
172174
override val name = "NativeViewGestureHandler"

packages/react-native-gesture-handler/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerDetectorView.kt

Lines changed: 66 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.swmansion.gesturehandler.react
22

33
import android.content.Context
4+
import android.view.View
45
import com.facebook.react.bridge.ReadableArray
56
import com.facebook.react.uimanager.ThemedReactContext
67
import com.facebook.react.uimanager.UIManagerHelper
@@ -12,9 +13,9 @@ class RNGestureHandlerDetectorView(context: Context) : ReactViewGroup(context) {
1213
private val reactContext: ThemedReactContext
1314
get() = context as ThemedReactContext
1415
private var handlersToAttach: List<Int>? = null
15-
private var attachedHandlers = listOf<Int>()
16+
private var nativeHandlersToAttach: MutableSet<Int> = mutableSetOf()
17+
private var attachedHandlers: MutableSet<Int> = mutableSetOf()
1618
private var moduleId: Int = -1
17-
private var dispatchesAnimatedEvents: Boolean = false
1819

1920
fun setHandlerTags(handlerTags: ReadableArray?) {
2021
val newHandlers = handlerTags?.toArrayList()?.map { (it as Double).toInt() } ?: emptyList()
@@ -36,8 +37,24 @@ class RNGestureHandlerDetectorView(context: Context) : ReactViewGroup(context) {
3637
handlersToAttach = null
3738
}
3839

39-
fun setDispatchesAnimatedEvents(dispatchesAnimatedEvents: Boolean) {
40-
this.dispatchesAnimatedEvents = dispatchesAnimatedEvents
40+
private fun shouldAttachGestureToChildView(tag: Int): Boolean {
41+
val registry = RNGestureHandlerModule.registries[moduleId]
42+
?: throw Exception("Tried to access a non-existent registry")
43+
44+
return registry.getHandler(tag)?.wantsToAttachDirectlyToView() ?: false
45+
}
46+
47+
// We override this `addView` because it is called inside `addView(child: View?, index: Int)`
48+
override fun addView(child: View, index: Int, params: LayoutParams?) {
49+
super.addView(child, index, params)
50+
51+
tryAttachHandlerToChildView(child.id)
52+
}
53+
54+
override fun removeViewAt(index: Int) {
55+
detachNativeGestureHandlers()
56+
57+
super.removeViewAt(index)
4158
}
4259

4360
private fun attachHandlers(newHandlers: List<Int>) {
@@ -55,19 +72,53 @@ class RNGestureHandlerDetectorView(context: Context) : ReactViewGroup(context) {
5572
}
5673

5774
for (entry in changes) {
75+
val tag = entry.key
76+
5877
if (entry.value == GestureHandlerMutation.Attach) {
59-
// TODO: Attach to the child when attached gesture is a NativeGestureHandler, track children changes then
60-
registry.attachHandlerToView(
61-
entry.key,
62-
this.id,
63-
if (dispatchesAnimatedEvents) {
64-
GestureHandler.ACTION_TYPE_NATIVE_DETECTOR_ANIMATED_EVENT
65-
} else {
66-
GestureHandler.ACTION_TYPE_NATIVE_DETECTOR
67-
},
68-
)
78+
// It might happen that `attachHandlers` will be called before children are added into view hierarchy. In that case we cannot
79+
// attach `NativeViewGestureHandlers` here and we have to do it in `addView` method.
80+
if (shouldAttachGestureToChildView(tag)) {
81+
nativeHandlersToAttach.add(tag)
82+
} else {
83+
registry.attachHandlerToView(tag, this.id, GestureHandler.ACTION_TYPE_NATIVE_DETECTOR)
84+
85+
attachedHandlers.add(tag)
86+
}
6987
} else if (entry.value == GestureHandlerMutation.Detach) {
70-
registry.detachHandler(entry.key)
88+
registry.detachHandler(tag)
89+
attachedHandlers.remove(tag)
90+
}
91+
}
92+
93+
// This covers the case where `NativeViewGestureHandlers` are attached after child views were created.
94+
val child = getChildAt(0)
95+
96+
if (child != null) {
97+
tryAttachHandlerToChildView(child.id)
98+
}
99+
}
100+
101+
private fun tryAttachHandlerToChildView(childId: Int) {
102+
val registry = RNGestureHandlerModule.registries[moduleId]
103+
?: throw Exception("Tried to access a non-existent registry")
104+
105+
for (tag in nativeHandlersToAttach) {
106+
registry.attachHandlerToView(tag, childId, GestureHandler.ACTION_TYPE_NATIVE_DETECTOR)
107+
108+
attachedHandlers.add(tag)
109+
}
110+
111+
nativeHandlersToAttach.clear()
112+
}
113+
114+
private fun detachNativeGestureHandlers() {
115+
val registry = RNGestureHandlerModule.registries[moduleId]
116+
?: throw Exception("Tried to access a non-existent registry")
117+
118+
for (tag in attachedHandlers) {
119+
if (shouldAttachGestureToChildView(tag)) {
120+
registry.detachHandler(tag)
121+
attachedHandlers.remove(tag)
71122
}
72123
}
73124
}

packages/react-native-gesture-handler/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerDetectorViewManager.kt

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,4 @@ class RNGestureHandlerDetectorViewManager :
3636
override fun setModuleId(view: RNGestureHandlerDetectorView, value: Int) {
3737
view.setModuleId(value)
3838
}
39-
40-
override fun setDispatchesAnimatedEvents(view: RNGestureHandlerDetectorView, value: Boolean) {
41-
view.setDispatchesAnimatedEvents(value)
42-
}
4339
}

packages/react-native-gesture-handler/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerEvent.kt

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ class RNGestureHandlerEvent private constructor() : Event<RNGestureHandlerEvent>
1818
private var dataBuilder: GestureHandlerEventDataBuilder<*>? = null
1919
private var coalescingKey: Short = 0
2020
private var actionType: Int = GestureHandler.ACTION_TYPE_NATIVE_ANIMATED_EVENT
21+
private var useAnimatedEvent = false
2122

2223
// On the new architecture, native animated expects event names prefixed with `top` instead of `on`,
2324
// since we know when the native animated node is the target of the event we can use the different
@@ -32,11 +33,18 @@ class RNGestureHandlerEvent private constructor() : Event<RNGestureHandlerEvent>
3233
dataBuilder: GestureHandlerEventDataBuilder<T>,
3334
useNativeAnimatedName: Boolean,
3435
) {
35-
val view = handler.view!!
36+
val view = if (handler.actionType == GestureHandler.ACTION_TYPE_NATIVE_DETECTOR) {
37+
handler.viewForEvents!!
38+
} else {
39+
handler.view!!
40+
}
41+
3642
super.init(UIManagerHelper.getSurfaceId(view), view.id)
43+
3744
this.actionType = actionType
3845
this.dataBuilder = dataBuilder
3946
this.useTopPrefixedName = useNativeAnimatedName
47+
this.useAnimatedEvent = useAnimatedEvent
4048
coalescingKey = handler.eventCoalescingKey
4149
}
4250

@@ -45,7 +53,7 @@ class RNGestureHandlerEvent private constructor() : Event<RNGestureHandlerEvent>
4553
EVENTS_POOL.release(this)
4654
}
4755

48-
override fun getEventName() = if (actionType == GestureHandler.ACTION_TYPE_NATIVE_DETECTOR_ANIMATED_EVENT) {
56+
override fun getEventName() = if (actionType == GestureHandler.ACTION_TYPE_NATIVE_DETECTOR && useTopPrefixedName) {
4957
NATIVE_DETECTOR_ANIMATED_EVENT_NAME
5058
} else if (useTopPrefixedName) {
5159
NATIVE_ANIMATED_EVENT_NAME
@@ -57,9 +65,7 @@ class RNGestureHandlerEvent private constructor() : Event<RNGestureHandlerEvent>
5765

5866
override fun getCoalescingKey() = coalescingKey
5967

60-
override fun getEventData(): WritableMap = if (actionType == GestureHandler.ACTION_TYPE_NATIVE_DETECTOR ||
61-
actionType == GestureHandler.ACTION_TYPE_NATIVE_DETECTOR_ANIMATED_EVENT
62-
) {
68+
override fun getEventData(): WritableMap = if (actionType == GestureHandler.ACTION_TYPE_NATIVE_DETECTOR) {
6369
createNativeEventData(dataBuilder!!)
6470
} else {
6571
createEventData(dataBuilder!!)

packages/react-native-gesture-handler/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerEventDispatcher.kt

Lines changed: 25 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -69,35 +69,23 @@ class RNGestureHandlerEventDispatcher(private val reactApplicationContext: React
6969
sendEventForDeviceEvent(RNGestureHandlerEvent.EVENT_NAME, data)
7070
}
7171
GestureHandler.ACTION_TYPE_NATIVE_DETECTOR -> {
72-
val view = handler.view
73-
if (view is RNGestureHandlerDetectorView) {
74-
val event = RNGestureHandlerEvent.obtain(
75-
handler,
76-
handler.actionType,
77-
handlerFactory.createEventBuilder(handler),
78-
)
79-
view.dispatchEvent(event)
80-
}
81-
}
82-
// In case of a native detector with animated event listener, dispatch the event twice:
83-
// once for the animated event, second for any JS callbacks
84-
GestureHandler.ACTION_TYPE_NATIVE_DETECTOR_ANIMATED_EVENT -> {
85-
val view = handler.view
86-
if (view is RNGestureHandlerDetectorView) {
72+
if (handler.dispatchesAnimatedEvents) {
8773
val animatedEvent = RNGestureHandlerEvent.obtain(
8874
handler,
8975
handler.actionType,
9076
handlerFactory.createEventBuilder(handler),
77+
true,
9178
)
92-
view.dispatchEvent(animatedEvent)
93-
94-
val event = RNGestureHandlerEvent.obtain(
95-
handler,
96-
GestureHandler.ACTION_TYPE_NATIVE_DETECTOR,
97-
handlerFactory.createEventBuilder(handler),
98-
)
99-
view.dispatchEvent(event)
79+
handler.viewForEvents!!.dispatchEvent(animatedEvent)
10080
}
81+
82+
val event = RNGestureHandlerEvent.obtain(
83+
handler,
84+
handler.actionType,
85+
handlerFactory.createEventBuilder(handler),
86+
)
87+
88+
handler.viewForEvents!!.dispatchEvent(event)
10189
}
10290
}
10391
}
@@ -144,18 +132,16 @@ class RNGestureHandlerEventDispatcher(private val reactApplicationContext: React
144132
sendEventForDeviceEvent(RNGestureHandlerStateChangeEvent.EVENT_NAME, data)
145133
}
146134

147-
GestureHandler.ACTION_TYPE_NATIVE_DETECTOR, GestureHandler.ACTION_TYPE_NATIVE_DETECTOR_ANIMATED_EVENT -> {
148-
val view = handler.view
149-
if (view is RNGestureHandlerDetectorView) {
150-
val event = RNGestureHandlerStateChangeEvent.obtain(
151-
handler,
152-
newState,
153-
oldState,
154-
handler.actionType,
155-
handlerFactory.createEventBuilder(handler),
156-
)
157-
view.dispatchEvent(event)
158-
}
135+
GestureHandler.ACTION_TYPE_NATIVE_DETECTOR -> {
136+
val event = RNGestureHandlerStateChangeEvent.obtain(
137+
handler,
138+
newState,
139+
oldState,
140+
handler.actionType,
141+
handlerFactory.createEventBuilder(handler),
142+
)
143+
144+
handler.viewForEvents!!.dispatchEvent(event)
159145
}
160146
}
161147
}
@@ -187,12 +173,10 @@ class RNGestureHandlerEventDispatcher(private val reactApplicationContext: React
187173
val data = RNGestureHandlerTouchEvent.createEventData(handler)
188174
sendEventForDeviceEvent(RNGestureHandlerEvent.EVENT_NAME, data)
189175
}
190-
GestureHandler.ACTION_TYPE_NATIVE_DETECTOR, GestureHandler.ACTION_TYPE_NATIVE_DETECTOR_ANIMATED_EVENT -> {
191-
val view = handler.view
192-
if (view is RNGestureHandlerDetectorView) {
193-
val event = RNGestureHandlerTouchEvent.obtain(handler, handler.actionType)
194-
view.dispatchEvent(event)
195-
}
176+
GestureHandler.ACTION_TYPE_NATIVE_DETECTOR -> {
177+
val event = RNGestureHandlerTouchEvent.obtain(handler, handler.actionType)
178+
179+
handler.viewForEvents!!.dispatchEvent(event)
196180
}
197181
}
198182
}

packages/react-native-gesture-handler/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerStateChangeEvent.kt

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,14 @@ class RNGestureHandlerStateChangeEvent private constructor() : Event<RNGestureHa
2727
actionType: Int,
2828
dataBuilder: GestureHandlerEventDataBuilder<T>,
2929
) {
30-
val view = handler.view!!
30+
val view = if (handler.actionType == GestureHandler.ACTION_TYPE_NATIVE_DETECTOR) {
31+
handler.viewForEvents!!
32+
} else {
33+
handler.view!!
34+
}
35+
3136
super.init(UIManagerHelper.getSurfaceId(view), view.id)
37+
3238
this.dataBuilder = dataBuilder
3339
this.newState = newState
3440
this.oldState = oldState
@@ -50,9 +56,7 @@ class RNGestureHandlerStateChangeEvent private constructor() : Event<RNGestureHa
5056
// TODO: coalescing
5157
override fun getCoalescingKey(): Short = 0
5258

53-
override fun getEventData(): WritableMap = if (actionType == GestureHandler.ACTION_TYPE_NATIVE_DETECTOR ||
54-
actionType == GestureHandler.ACTION_TYPE_NATIVE_DETECTOR_ANIMATED_EVENT
55-
) {
59+
override fun getEventData(): WritableMap = if (actionType == GestureHandler.ACTION_TYPE_NATIVE_DETECTOR) {
5660
createNativeEventData(dataBuilder!!, newState, oldState)
5761
} else {
5862
createEventData(dataBuilder!!, newState, oldState)

0 commit comments

Comments
 (0)