Skip to content

Commit 6dffddb

Browse files
committed
Merge branch 'next' into @akwasniewski/logic-detector-native-gestures
2 parents 3cf56a6 + 83110b2 commit 6dffddb

File tree

24 files changed

+365
-127
lines changed

24 files changed

+365
-127
lines changed

apps/basic-example/src/NativeDetector.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import * as React from 'react';
22
import { Animated, Button, useAnimatedValue } from 'react-native';
33
import {
44
GestureHandlerRootView,
5-
NativeDetector,
5+
GestureDetector,
66
usePan,
77
} from 'react-native-gesture-handler';
88

@@ -32,7 +32,7 @@ export default function App() {
3232
/>
3333

3434
{visible && (
35-
<NativeDetector gesture={gesture}>
35+
<GestureDetector gesture={gesture}>
3636
<Animated.View
3737
style={[
3838
{
@@ -48,7 +48,7 @@ export default function App() {
4848
{ transform: [{ translateX: value }] },
4949
]}
5050
/>
51-
</NativeDetector>
51+
</GestureDetector>
5252
)}
5353
</GestureHandlerRootView>
5454
);

apps/basic-example/src/Text.tsx

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@ import { StyleSheet, Text, View } from 'react-native';
33
import {
44
Gesture,
55
GestureDetector,
6-
LogicDetector,
7-
NativeDetector,
6+
InterceptingGestureDetector,
87
useTap,
98
} from 'react-native-gesture-handler';
109

@@ -37,24 +36,24 @@ function NativeDetectorExample() {
3736
<Text style={styles.header}>
3837
Native Detector example - this one should work
3938
</Text>
40-
<NativeDetector gesture={tapAll}>
39+
<InterceptingGestureDetector gesture={tapAll}>
4140
<Text style={{ fontSize: 18, textAlign: 'center' }}>
4241
Some text example running with RNGH
43-
<LogicDetector gesture={tapFirstPart}>
42+
<GestureDetector gesture={tapFirstPart}>
4443
<Text style={{ fontSize: 24, color: COLORS.NAVY }}>
4544
{' '}
4645
try tapping on this part
4746
</Text>
48-
</LogicDetector>
49-
<LogicDetector gesture={tapSecondPart}>
47+
</GestureDetector>
48+
<GestureDetector gesture={tapSecondPart}>
5049
<Text style={{ fontSize: 28, color: COLORS.KINDA_BLUE }}>
5150
{' '}
5251
or on this part
5352
</Text>
54-
</LogicDetector>
53+
</GestureDetector>
5554
this part is not special :(
5655
</Text>
57-
</NativeDetector>
56+
</InterceptingGestureDetector>
5857
</View>
5958
);
6059
}

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ open class GestureHandler {
8282
}
8383
var actionType = 0
8484

85+
var forceReinitializeDuringOnHandle = false
8586
var changedTouchesPayload: WritableArray? = null
8687
private set
8788
var allTouchesPayload: WritableArray? = null
@@ -755,6 +756,7 @@ open class GestureHandler {
755756
// if the handler is waiting for failure of other one)
756757
open fun resetProgress() {}
757758

759+
protected open fun initialize(event: MotionEvent, sourceEvent: MotionEvent) {}
758760
protected open fun onHandle(event: MotionEvent, sourceEvent: MotionEvent) {
759761
moveToState(STATE_FAILED)
760762
}

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

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -287,15 +287,7 @@ class GestureHandlerOrchestrator(
287287
val action = sourceEvent.actionMasked
288288
val event = transformEventToViewCoords(handler.view, MotionEvent.obtain(sourceEvent))
289289

290-
// Touch events are sent before the handler itself has a chance to process them,
291-
// mainly because `onTouchesUp` should be send before gesture finishes. This means that
292-
// the first `onTouchesDown` event is sent before a gesture begins, activation in
293-
// callback for this event causes problems because the handler doesn't have a chance
294-
// to initialize itself with starting values of pointer (in pan this causes translation
295-
// to be equal to the coordinates of the pointer). The simplest solution is to send
296-
// the first `onTouchesDown` event after the handler processes it and changes state
297-
// to `BEGAN`.
298-
if (handler.needsPointerData && handler.state != 0) {
290+
if (handler.needsPointerData) {
299291
handler.updatePointerData(event, sourceEvent)
300292
}
301293

@@ -317,10 +309,6 @@ class GestureHandlerOrchestrator(
317309
handler.dispatchHandlerUpdate(event)
318310
}
319311

320-
if (handler.needsPointerData && isFirstEvent) {
321-
handler.updatePointerData(event, sourceEvent)
322-
}
323-
324312
// if event was of type UP or POINTER_UP we request handler to stop tracking now that
325313
// the event has been dispatched
326314
if (action == MotionEvent.ACTION_UP ||

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

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,14 +65,23 @@ class LongPressGestureHandler(context: Context) : GestureHandler() {
6565
return Pair(x, y)
6666
}
6767

68+
override fun initialize(event: MotionEvent, sourceEvent: MotionEvent) {
69+
previousTime = SystemClock.uptimeMillis()
70+
startTime = previousTime
71+
}
72+
6873
override fun onHandle(event: MotionEvent, sourceEvent: MotionEvent) {
6974
if (!shouldActivateWithMouse(sourceEvent)) {
7075
return
7176
}
7277

78+
if (forceReinitializeDuringOnHandle) {
79+
forceReinitializeDuringOnHandle = false
80+
initialize(event, sourceEvent)
81+
}
82+
7383
if (state == STATE_UNDETERMINED) {
74-
previousTime = SystemClock.uptimeMillis()
75-
startTime = previousTime
84+
initialize(event, sourceEvent)
7685
begin()
7786

7887
val (x, y) = getAverageCoords(sourceEvent)

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

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -148,11 +148,25 @@ class PanGestureHandler(context: Context?) : GestureHandler() {
148148
return failOffsetYEnd != MIN_VALUE_IGNORE && dy > failOffsetYEnd
149149
}
150150

151+
override fun initialize(event: MotionEvent, sourceEvent: MotionEvent) {
152+
resetProgress()
153+
offsetX = 0f
154+
offsetY = 0f
155+
velocityX = 0f
156+
velocityY = 0f
157+
velocityTracker = VelocityTracker.obtain()
158+
}
159+
151160
override fun onHandle(event: MotionEvent, sourceEvent: MotionEvent) {
152161
if (!shouldActivateWithMouse(sourceEvent)) {
153162
return
154163
}
155164

165+
if (forceReinitializeDuringOnHandle) {
166+
forceReinitializeDuringOnHandle = false
167+
initialize(event, sourceEvent)
168+
}
169+
156170
if (event.getToolType(0) == MotionEvent.TOOL_TYPE_STYLUS) {
157171
stylusData = StylusData.fromEvent(event)
158172
}
@@ -174,12 +188,7 @@ class PanGestureHandler(context: Context?) : GestureHandler() {
174188
lastY = getLastPointerY(sourceEvent, averageTouches)
175189
}
176190
if (state == STATE_UNDETERMINED && sourceEvent.pointerCount >= minPointers) {
177-
resetProgress()
178-
offsetX = 0f
179-
offsetY = 0f
180-
velocityX = 0f
181-
velocityY = 0f
182-
velocityTracker = VelocityTracker.obtain()
191+
initialize(event, sourceEvent)
183192
addVelocityMovement(velocityTracker, sourceEvent)
184193
begin()
185194

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

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -49,18 +49,26 @@ class PinchGestureHandler : GestureHandler() {
4949
}
5050
}
5151

52-
override fun onHandle(event: MotionEvent, sourceEvent: MotionEvent) {
53-
if (state == STATE_UNDETERMINED) {
54-
val context = view!!.context
55-
resetProgress()
56-
scaleGestureDetector = ScaleGestureDetector(context, gestureListener)
57-
val configuration = ViewConfiguration.get(context)
58-
spanSlop = configuration.scaledTouchSlop.toFloat()
52+
override fun initialize(event: MotionEvent, sourceEvent: MotionEvent) {
53+
val context = view!!.context
54+
resetProgress()
55+
scaleGestureDetector = ScaleGestureDetector(context, gestureListener)
56+
val configuration = ViewConfiguration.get(context)
57+
spanSlop = configuration.scaledTouchSlop.toFloat()
5958

60-
// set the focal point to the position of the first pointer as NaN causes the event not to arrive
61-
this.focalPointX = event.x
62-
this.focalPointY = event.y
59+
// set the focal point to the position of the first pointer as NaN causes the event not to arrive
60+
this.focalPointX = event.x
61+
this.focalPointY = event.y
62+
}
6363

64+
override fun onHandle(event: MotionEvent, sourceEvent: MotionEvent) {
65+
if (forceReinitializeDuringOnHandle) {
66+
forceReinitializeDuringOnHandle = false
67+
initialize(event, sourceEvent)
68+
}
69+
70+
if (state == STATE_UNDETERMINED) {
71+
initialize(event, sourceEvent)
6472
begin()
6573
}
6674
scaleGestureDetector?.onTouchEvent(sourceEvent)

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

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -39,15 +39,23 @@ class RotationGestureHandler : GestureHandler() {
3939
}
4040
}
4141

42-
override fun onHandle(event: MotionEvent, sourceEvent: MotionEvent) {
43-
if (state == STATE_UNDETERMINED) {
44-
resetProgress()
45-
rotationGestureDetector = RotationGestureDetector(gestureListener)
42+
override fun initialize(event: MotionEvent, sourceEvent: MotionEvent) {
43+
resetProgress()
44+
rotationGestureDetector = RotationGestureDetector(gestureListener)
4645

47-
// set the anchor to the position of the first pointer as NaN causes the event not to arrive
48-
this.anchorX = event.x
49-
this.anchorY = event.y
46+
// set the anchor to the position of the first pointer as NaN causes the event not to arrive
47+
this.anchorX = event.x
48+
this.anchorY = event.y
49+
}
5050

51+
override fun onHandle(event: MotionEvent, sourceEvent: MotionEvent) {
52+
if (forceReinitializeDuringOnHandle) {
53+
forceReinitializeDuringOnHandle = false
54+
initialize(event, sourceEvent)
55+
}
56+
57+
if (state == STATE_UNDETERMINED) {
58+
initialize(event, sourceEvent)
5159
begin()
5260
}
5361
rotationGestureDetector?.onTouchEvent(sourceEvent)

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

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -81,18 +81,27 @@ class TapGestureHandler : GestureHandler() {
8181
return maxDist != MAX_VALUE_IGNORE && dist > maxDist * maxDist
8282
}
8383

84+
override fun initialize(event: MotionEvent, sourceEvent: MotionEvent) {
85+
offsetX = 0f
86+
offsetY = 0f
87+
startX = getLastPointerX(sourceEvent, true)
88+
startY = getLastPointerY(sourceEvent, true)
89+
}
90+
8491
override fun onHandle(event: MotionEvent, sourceEvent: MotionEvent) {
8592
if (!shouldActivateWithMouse(sourceEvent)) {
8693
return
8794
}
8895

96+
if (forceReinitializeDuringOnHandle) {
97+
forceReinitializeDuringOnHandle = false
98+
initialize(event, sourceEvent)
99+
}
100+
89101
val state = state
90102
val action = sourceEvent.actionMasked
91103
if (state == STATE_UNDETERMINED) {
92-
offsetX = 0f
93-
offsetY = 0f
94-
startX = getLastPointerX(sourceEvent, true)
95-
startY = getLastPointerY(sourceEvent, true)
104+
initialize(event, sourceEvent)
96105
}
97106
if (action == MotionEvent.ACTION_POINTER_UP || action == MotionEvent.ACTION_POINTER_DOWN) {
98107
offsetX += lastX - startX

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,16 @@ class RNGestureHandlerModule(reactContext: ReactApplicationContext?) :
140140
UiThreadUtil.assertOnUiThread()
141141

142142
registry.getHandler(handlerTag)?.let { handler ->
143+
if (handler.state == GestureHandler.STATE_UNDETERMINED) {
144+
handler.forceReinitializeDuringOnHandle = true
145+
146+
// When going from UNDETERMINED to ACTIVE, force going through BEGAN to preserve
147+
// the correct state flow
148+
if (newState == GestureHandler.STATE_ACTIVE) {
149+
handler.begin()
150+
}
151+
}
152+
143153
when (newState) {
144154
GestureHandler.STATE_ACTIVE -> handler.activate(force = true)
145155
GestureHandler.STATE_BEGAN -> handler.begin()

0 commit comments

Comments
 (0)