react-native-gesture-handler 2.4.0 → 2.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -2
- package/android/build.gradle +28 -4
- package/android/lib/src/main/java/com/swmansion/gesturehandler/GestureHandler.kt +9 -5
- package/android/lib/src/main/java/com/swmansion/gesturehandler/GestureHandlerOrchestrator.kt +6 -1
- package/android/lib/src/main/java/com/swmansion/gesturehandler/NativeViewGestureHandler.kt +103 -22
- package/android/lib/src/main/java/com/swmansion/gesturehandler/PanGestureHandler.kt +29 -2
- package/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerButtonViewManager.kt +74 -84
- package/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerModule.kt +4 -0
- package/android/src/main/jni/Android.mk +1 -2
- package/android/src/paper/java/com/facebook/react/viewmanagers/RNGestureHandlerButtonManagerDelegate.java +12 -9
- package/android/src/paper/java/com/facebook/react/viewmanagers/RNGestureHandlerButtonManagerInterface.java +1 -0
- package/ios/Handlers/RNFlingHandler.m +43 -1
- package/ios/Handlers/{RNNativeViewHandler.m → RNNativeViewHandler.mm} +13 -1
- package/ios/Handlers/RNPanHandler.m +27 -0
- package/ios/RNGestureHandler.h +1 -0
- package/ios/RNGestureHandler.m +22 -4
- package/ios/RNGestureHandlerManager.mm +10 -2
- package/ios/RNGestureHandlerModule.mm +4 -1
- package/ios/RNManualActivationRecognizer.m +10 -3
- package/ios/RNRootViewGestureRecognizer.m +12 -1
- package/lib/commonjs/RNGestureHandlerModule.macos.js +81 -0
- package/lib/commonjs/RNGestureHandlerModule.macos.js.map +1 -0
- package/lib/commonjs/components/DrawerLayout.js +38 -11
- package/lib/commonjs/components/DrawerLayout.js.map +1 -1
- package/lib/commonjs/components/GestureButtons.js.map +1 -1
- package/lib/commonjs/components/touchables/GenericTouchable.js +4 -1
- package/lib/commonjs/components/touchables/GenericTouchable.js.map +1 -1
- package/lib/commonjs/fabric/RNGestureHandlerButtonNativeComponent.js.map +1 -1
- package/lib/commonjs/handlers/ForceTouchGestureHandler.js +2 -1
- package/lib/commonjs/handlers/ForceTouchGestureHandler.js.map +1 -1
- package/lib/commonjs/handlers/PanGestureHandler.js +1 -1
- package/lib/commonjs/handlers/PanGestureHandler.js.map +1 -1
- package/lib/commonjs/handlers/PressabilityDebugView.js +14 -0
- package/lib/commonjs/handlers/PressabilityDebugView.js.map +1 -0
- package/lib/commonjs/handlers/PressabilityDebugView.web.js +12 -0
- package/lib/commonjs/handlers/PressabilityDebugView.web.js.map +1 -0
- package/lib/commonjs/handlers/createHandler.js +25 -11
- package/lib/commonjs/handlers/createHandler.js.map +1 -1
- package/lib/commonjs/handlers/gestureHandlerCommon.js.map +1 -1
- package/lib/commonjs/handlers/gestures/GestureDetector.js +83 -63
- package/lib/commonjs/handlers/gestures/GestureDetector.js.map +1 -1
- package/lib/commonjs/handlers/gestures/gesture.js +13 -2
- package/lib/commonjs/handlers/gestures/gesture.js.map +1 -1
- package/lib/commonjs/handlers/gestures/gestureStateManager.js +13 -9
- package/lib/commonjs/handlers/gestures/gestureStateManager.js.map +1 -1
- package/lib/commonjs/handlers/gestures/panGesture.js +5 -0
- package/lib/commonjs/handlers/gestures/panGesture.js.map +1 -1
- package/lib/commonjs/mocks.js +2 -0
- package/lib/commonjs/mocks.js.map +1 -1
- package/lib/commonjs/utils.js +6 -3
- package/lib/commonjs/utils.js.map +1 -1
- package/lib/commonjs/web/utils.js.map +1 -1
- package/lib/module/RNGestureHandlerModule.macos.js +57 -0
- package/lib/module/RNGestureHandlerModule.macos.js.map +1 -0
- package/lib/module/components/DrawerLayout.js +38 -11
- package/lib/module/components/DrawerLayout.js.map +1 -1
- package/lib/module/components/GestureButtons.js.map +1 -1
- package/lib/module/components/touchables/GenericTouchable.js +4 -1
- package/lib/module/components/touchables/GenericTouchable.js.map +1 -1
- package/lib/module/fabric/RNGestureHandlerButtonNativeComponent.js.map +1 -1
- package/lib/module/handlers/ForceTouchGestureHandler.js +1 -1
- package/lib/module/handlers/ForceTouchGestureHandler.js.map +1 -1
- package/lib/module/handlers/PanGestureHandler.js +1 -1
- package/lib/module/handlers/PanGestureHandler.js.map +1 -1
- package/lib/module/handlers/PressabilityDebugView.js +3 -0
- package/lib/module/handlers/PressabilityDebugView.js.map +1 -0
- package/lib/module/handlers/PressabilityDebugView.web.js +5 -0
- package/lib/module/handlers/PressabilityDebugView.web.js.map +1 -0
- package/lib/module/handlers/createHandler.js +26 -12
- package/lib/module/handlers/createHandler.js.map +1 -1
- package/lib/module/handlers/gestureHandlerCommon.js.map +1 -1
- package/lib/module/handlers/gestures/GestureDetector.js +83 -63
- package/lib/module/handlers/gestures/GestureDetector.js.map +1 -1
- package/lib/module/handlers/gestures/gesture.js +13 -2
- package/lib/module/handlers/gestures/gesture.js.map +1 -1
- package/lib/module/handlers/gestures/gestureStateManager.js +13 -9
- package/lib/module/handlers/gestures/gestureStateManager.js.map +1 -1
- package/lib/module/handlers/gestures/panGesture.js +5 -0
- package/lib/module/handlers/gestures/panGesture.js.map +1 -1
- package/lib/module/mocks.js +2 -0
- package/lib/module/mocks.js.map +1 -1
- package/lib/module/utils.js +2 -1
- package/lib/module/utils.js.map +1 -1
- package/lib/module/web/utils.js.map +1 -1
- package/lib/typescript/RNGestureHandlerModule.macos.d.ts +34 -0
- package/lib/typescript/RNGestureHandlerModule.web.d.ts +1 -1
- package/lib/typescript/components/DrawerLayout.d.ts +3 -0
- package/lib/typescript/components/GestureButtons.d.ts +6 -0
- package/lib/typescript/fabric/RNGestureHandlerButtonNativeComponent.d.ts +1 -0
- package/lib/typescript/handlers/ForceTouchGestureHandler.d.ts +2 -2
- package/lib/typescript/handlers/PanGestureHandler.d.ts +2 -1
- package/lib/typescript/handlers/PressabilityDebugView.d.ts +1 -0
- package/lib/typescript/handlers/PressabilityDebugView.web.d.ts +1 -0
- package/lib/typescript/handlers/gestureHandlerCommon.d.ts +1 -0
- package/lib/typescript/handlers/gestures/GestureDetector.d.ts +2 -1
- package/lib/typescript/handlers/gestures/gesture.d.ts +3 -0
- package/lib/typescript/handlers/gestures/panGesture.d.ts +1 -0
- package/lib/typescript/mocks.d.ts +1 -0
- package/lib/typescript/web/NodeManager.d.ts +2 -2
- package/package.json +1 -1
- package/src/RNGestureHandlerModule.macos.ts +62 -0
- package/src/components/DrawerLayout.tsx +34 -10
- package/src/components/GestureButtons.tsx +7 -0
- package/src/components/touchables/GenericTouchable.tsx +1 -0
- package/src/fabric/RNGestureHandlerButtonNativeComponent.ts +1 -0
- package/src/handlers/ForceTouchGestureHandler.ts +3 -2
- package/src/handlers/PanGestureHandler.ts +2 -0
- package/src/handlers/PressabilityDebugView.tsx +2 -0
- package/src/handlers/PressabilityDebugView.web.tsx +4 -0
- package/src/handlers/{createHandler.ts → createHandler.tsx} +32 -17
- package/src/handlers/gestureHandlerCommon.ts +2 -0
- package/src/handlers/gestures/GestureDetector.tsx +107 -81
- package/src/handlers/gestures/gesture.ts +16 -0
- package/src/handlers/gestures/gestureStateManager.ts +13 -8
- package/src/handlers/gestures/panGesture.ts +5 -0
- package/src/mocks.ts +2 -0
- package/src/utils.ts +3 -1
- package/src/web/utils.ts +1 -1
- package/ios/RNGestureHandler.xcodeproj/project.xcworkspace/xcuserdata/jakubpiasecki.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
- package/ios/RNGestureHandler.xcodeproj/xcuserdata/jakubpiasecki.xcuserdatad/xcschemes/xcschememanagement.plist +0 -19
package/README.md
CHANGED
|
@@ -24,7 +24,7 @@ Check out our dedicated documentation page for info about this library, API refe
|
|
|
24
24
|
If you want to play with the API but don't feel like trying it on a real app, you can run the example project. Clone the repo, go to the `example` folder and run:
|
|
25
25
|
|
|
26
26
|
```bash
|
|
27
|
-
|
|
27
|
+
yarn install
|
|
28
28
|
```
|
|
29
29
|
|
|
30
30
|
If you are running on ios, run `pod install` in the ios folder
|
|
@@ -44,7 +44,8 @@ You will need to have an Android or iOS device or emulator connected as well as
|
|
|
44
44
|
| <1.1.0 | 0.50.0+ |
|
|
45
45
|
|
|
46
46
|
It may be possible to use newer versions of react-native-gesture-handler on React Native with version <= 0.59 by reverse Jetifying.
|
|
47
|
-
Read more on that here https://github.com/mikehardy/jetifier#to-reverse-jetify--convert-node_modules-dependencies-to-support-libraries
|
|
47
|
+
Read more on that here <https://github.com/mikehardy/jetifier#to-reverse-jetify--convert-node_modules-dependencies-to-support-libraries>
|
|
48
|
+
|
|
48
49
|
## License
|
|
49
50
|
|
|
50
51
|
Gesture handler library is licensed under [The MIT License](LICENSE).
|
package/android/build.gradle
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import groovy.json.JsonSlurper
|
|
2
|
+
import java.nio.file.Paths
|
|
2
3
|
|
|
3
4
|
buildscript {
|
|
4
5
|
def kotlin_version = rootProject.ext.has('kotlinVersion') ? rootProject.ext.get('kotlinVersion') : project.properties['RNGH_kotlinVersion']
|
|
@@ -20,6 +21,20 @@ def isNewArchitectureEnabled() {
|
|
|
20
21
|
return project.hasProperty("newArchEnabled") && project.newArchEnabled == "true"
|
|
21
22
|
}
|
|
22
23
|
|
|
24
|
+
def findNodeModulePath(baseDir, packageName) {
|
|
25
|
+
def basePath = baseDir.toPath().normalize()
|
|
26
|
+
// Node's module resolution algorithm searches up to the root directory,
|
|
27
|
+
// after which the base path will be null
|
|
28
|
+
while (basePath) {
|
|
29
|
+
def candidatePath = Paths.get(basePath.toString(), "node_modules", packageName)
|
|
30
|
+
if (candidatePath.toFile().exists()) {
|
|
31
|
+
return candidatePath.toString()
|
|
32
|
+
}
|
|
33
|
+
basePath = basePath.getParent()
|
|
34
|
+
}
|
|
35
|
+
return null
|
|
36
|
+
}
|
|
37
|
+
|
|
23
38
|
if (isNewArchitectureEnabled()) {
|
|
24
39
|
apply plugin: 'com.facebook.react'
|
|
25
40
|
}
|
|
@@ -51,6 +66,15 @@ repositories {
|
|
|
51
66
|
android {
|
|
52
67
|
compileSdkVersion safeExtGet("compileSdkVersion", 28)
|
|
53
68
|
|
|
69
|
+
// Used to override the NDK path/version on internal CI or by allowing
|
|
70
|
+
// users to customize the NDK path/version from their root project (e.g. for M1 support)
|
|
71
|
+
if (rootProject.hasProperty("ndkPath")) {
|
|
72
|
+
ndkPath rootProject.ext.ndkPath
|
|
73
|
+
}
|
|
74
|
+
if (rootProject.hasProperty("ndkVersion")) {
|
|
75
|
+
ndkVersion rootProject.ext.ndkVersion
|
|
76
|
+
}
|
|
77
|
+
|
|
54
78
|
defaultConfig {
|
|
55
79
|
minSdkVersion safeExtGet('minSdkVersion', 16)
|
|
56
80
|
targetSdkVersion safeExtGet('targetSdkVersion', 28)
|
|
@@ -66,8 +90,8 @@ android {
|
|
|
66
90
|
"NDK_TOOLCHAIN_VERSION=clang",
|
|
67
91
|
"GENERATED_SRC_DIR=${appProject.buildDir}/generated/source",
|
|
68
92
|
"PROJECT_BUILD_DIR=${appProject.buildDir}",
|
|
69
|
-
"REACT_ANDROID_DIR=${appProject.rootDir
|
|
70
|
-
"REACT_ANDROID_BUILD_DIR=${appProject.rootDir
|
|
93
|
+
"REACT_ANDROID_DIR=${findNodeModulePath(appProject.rootDir, "react-native") ?: "../node_modules/react-native/"}/ReactAndroid",
|
|
94
|
+
"REACT_ANDROID_BUILD_DIR=${findNodeModulePath(appProject.rootDir, "react-native") ?: "../node_modules/react-native/"}/ReactAndroid/build"
|
|
71
95
|
cFlags "-Wall", "-Werror", "-fexceptions", "-frtti", "-DWITH_INSPECTOR=1"
|
|
72
96
|
cppFlags "-std=c++17"
|
|
73
97
|
targets "rngesturehandler_modules"
|
|
@@ -148,9 +172,9 @@ dependencies {
|
|
|
148
172
|
|
|
149
173
|
if (isNewArchitectureEnabled()) {
|
|
150
174
|
react {
|
|
151
|
-
|
|
175
|
+
reactNativeDir = rootProject.file(findNodeModulePath(rootProject.rootDir, "react-native") ?: "../node_modules/react-native/")
|
|
152
176
|
jsRootDir = file("../src/fabric/")
|
|
153
|
-
codegenDir = rootProject.file("../node_modules/react-native-codegen/")
|
|
177
|
+
codegenDir = rootProject.file(findNodeModulePath(rootProject.rootDir, "react-native-codegen") ?: "../node_modules/react-native-codegen/")
|
|
154
178
|
libraryName = "rngesturehandler"
|
|
155
179
|
codegenJavaPackageName = "com.swmansion.gesturehandler"
|
|
156
180
|
}
|
|
@@ -172,8 +172,12 @@ open class GestureHandler<ConcreteGestureHandlerT : GestureHandler<ConcreteGestu
|
|
|
172
172
|
windowOffset[0] = 0
|
|
173
173
|
windowOffset[1] = 0
|
|
174
174
|
}
|
|
175
|
+
|
|
176
|
+
onPrepare()
|
|
175
177
|
}
|
|
176
178
|
|
|
179
|
+
protected open fun onPrepare() {}
|
|
180
|
+
|
|
177
181
|
private fun getWindow(context: Context?): Window? {
|
|
178
182
|
if (context == null) return null
|
|
179
183
|
if (context is Activity) return context.window
|
|
@@ -253,9 +257,9 @@ open class GestureHandler<ConcreteGestureHandlerT : GestureHandler<ConcreteGestu
|
|
|
253
257
|
}
|
|
254
258
|
initPointerProps(trackedPointersIDsCount)
|
|
255
259
|
var count = 0
|
|
256
|
-
val
|
|
257
|
-
val
|
|
258
|
-
event.
|
|
260
|
+
val deltaX = event.rawX - event.x
|
|
261
|
+
val deltaY = event.rawY - event.y
|
|
262
|
+
event.offsetLocation(deltaX, deltaY)
|
|
259
263
|
var index = 0
|
|
260
264
|
val size = event.pointerCount
|
|
261
265
|
while (index < size) {
|
|
@@ -298,8 +302,8 @@ open class GestureHandler<ConcreteGestureHandlerT : GestureHandler<ConcreteGestu
|
|
|
298
302
|
} catch (e: IllegalArgumentException) {
|
|
299
303
|
throw AdaptEventException(this, event, e)
|
|
300
304
|
}
|
|
301
|
-
event.
|
|
302
|
-
result.
|
|
305
|
+
event.offsetLocation(-deltaX, -deltaY)
|
|
306
|
+
result.offsetLocation(-deltaX, -deltaY)
|
|
303
307
|
return result
|
|
304
308
|
}
|
|
305
309
|
|
package/android/lib/src/main/java/com/swmansion/gesturehandler/GestureHandlerOrchestrator.kt
CHANGED
|
@@ -475,7 +475,12 @@ class GestureHandlerOrchestrator(
|
|
|
475
475
|
PointerEventsConfig.BOX_NONE -> {
|
|
476
476
|
// This view can't be the target, but its children might
|
|
477
477
|
if (view is ViewGroup) {
|
|
478
|
-
extractGestureHandlers(view, coords, pointerId)
|
|
478
|
+
extractGestureHandlers(view, coords, pointerId).also { found ->
|
|
479
|
+
// A child view is handling touch, also extract handlers attached to this view
|
|
480
|
+
if (found) {
|
|
481
|
+
recordViewHandlersForPointer(view, coords, pointerId)
|
|
482
|
+
}
|
|
483
|
+
}
|
|
479
484
|
} else false
|
|
480
485
|
}
|
|
481
486
|
PointerEventsConfig.AUTO -> {
|
|
@@ -3,13 +3,16 @@ package com.swmansion.gesturehandler
|
|
|
3
3
|
import android.os.SystemClock
|
|
4
4
|
import android.view.MotionEvent
|
|
5
5
|
import android.view.View
|
|
6
|
+
import android.view.ViewConfiguration
|
|
6
7
|
import android.view.ViewGroup
|
|
7
|
-
import com.
|
|
8
|
+
import com.facebook.react.views.textinput.ReactEditText
|
|
8
9
|
|
|
9
10
|
class NativeViewGestureHandler : GestureHandler<NativeViewGestureHandler>() {
|
|
10
11
|
private var shouldActivateOnStart = false
|
|
11
12
|
private var disallowInterruption = false
|
|
12
13
|
|
|
14
|
+
private var hook: NativeViewGestureHandlerHook = defaultHook
|
|
15
|
+
|
|
13
16
|
init {
|
|
14
17
|
setShouldCancelWhenOutside(true)
|
|
15
18
|
}
|
|
@@ -34,13 +37,17 @@ class NativeViewGestureHandler : GestureHandler<NativeViewGestureHandler>() {
|
|
|
34
37
|
}
|
|
35
38
|
|
|
36
39
|
override fun shouldRecognizeSimultaneously(handler: GestureHandler<*>): Boolean {
|
|
40
|
+
// if the gesture is marked by user as simultaneous with other or the hook return true
|
|
41
|
+
if (super.shouldRecognizeSimultaneously(handler) || hook.shouldRecognizeSimultaneously(handler)) {
|
|
42
|
+
return true
|
|
43
|
+
}
|
|
44
|
+
|
|
37
45
|
if (handler is NativeViewGestureHandler) {
|
|
38
46
|
// Special case when the peer handler is also an instance of NativeViewGestureHandler:
|
|
39
47
|
// For the `disallowInterruption` to work correctly we need to check the property when
|
|
40
48
|
// accessed as a peer, because simultaneous recognizers can be set on either side of the
|
|
41
49
|
// connection.
|
|
42
|
-
|
|
43
|
-
if (nativeWrapper.state == STATE_ACTIVE && nativeWrapper.disallowInterruption) {
|
|
50
|
+
if (handler.state == STATE_ACTIVE && handler.disallowInterruption) {
|
|
44
51
|
// other handler is active and it disallows interruption, we don't want to get into its way
|
|
45
52
|
return false
|
|
46
53
|
}
|
|
@@ -52,7 +59,7 @@ class NativeViewGestureHandler : GestureHandler<NativeViewGestureHandler>() {
|
|
|
52
59
|
// as it means the other handler has turned active and returning `true` would prevent it from
|
|
53
60
|
// interrupting the current handler
|
|
54
61
|
false
|
|
55
|
-
} else state == STATE_ACTIVE && canBeInterrupted
|
|
62
|
+
} else state == STATE_ACTIVE && canBeInterrupted && (!hook.shouldCancelRootViewGestureHandlerIfNecessary() || handler.tag > 0)
|
|
56
63
|
// otherwise we can only return `true` if already in an active state
|
|
57
64
|
}
|
|
58
65
|
|
|
@@ -60,19 +67,10 @@ class NativeViewGestureHandler : GestureHandler<NativeViewGestureHandler>() {
|
|
|
60
67
|
return !disallowInterruption
|
|
61
68
|
}
|
|
62
69
|
|
|
63
|
-
|
|
64
|
-
val view = view
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
return true
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
private fun afterGestureEnd() {
|
|
73
|
-
val view = view
|
|
74
|
-
if (view is StateChangeHook) {
|
|
75
|
-
view.afterGestureEnd()
|
|
70
|
+
override fun onPrepare() {
|
|
71
|
+
when (val view = view) {
|
|
72
|
+
is NativeViewGestureHandlerHook -> this.hook = view
|
|
73
|
+
is ReactEditText -> this.hook = EditTextHook(this, view)
|
|
76
74
|
}
|
|
77
75
|
}
|
|
78
76
|
|
|
@@ -84,7 +82,7 @@ class NativeViewGestureHandler : GestureHandler<NativeViewGestureHandler>() {
|
|
|
84
82
|
activate()
|
|
85
83
|
}
|
|
86
84
|
end()
|
|
87
|
-
afterGestureEnd()
|
|
85
|
+
hook.afterGestureEnd(event)
|
|
88
86
|
} else if (state == STATE_UNDETERMINED || state == STATE_BEGAN) {
|
|
89
87
|
when {
|
|
90
88
|
shouldActivateOnStart -> {
|
|
@@ -96,8 +94,11 @@ class NativeViewGestureHandler : GestureHandler<NativeViewGestureHandler>() {
|
|
|
96
94
|
view.onTouchEvent(event)
|
|
97
95
|
activate()
|
|
98
96
|
}
|
|
97
|
+
hook.wantsToHandleEventBeforeActivation() -> {
|
|
98
|
+
hook.handleEventBeforeActivation(event)
|
|
99
|
+
}
|
|
99
100
|
state != STATE_BEGAN -> {
|
|
100
|
-
if (
|
|
101
|
+
if (hook.canBegin()) {
|
|
101
102
|
begin()
|
|
102
103
|
} else {
|
|
103
104
|
cancel()
|
|
@@ -117,13 +118,93 @@ class NativeViewGestureHandler : GestureHandler<NativeViewGestureHandler>() {
|
|
|
117
118
|
view!!.onTouchEvent(event)
|
|
118
119
|
}
|
|
119
120
|
|
|
121
|
+
override fun onReset() {
|
|
122
|
+
this.hook = defaultHook
|
|
123
|
+
}
|
|
124
|
+
|
|
120
125
|
companion object {
|
|
121
126
|
private fun tryIntercept(view: View, event: MotionEvent) =
|
|
122
127
|
view is ViewGroup && view.onInterceptTouchEvent(event)
|
|
128
|
+
|
|
129
|
+
private val defaultHook = object : NativeViewGestureHandlerHook {}
|
|
123
130
|
}
|
|
124
131
|
|
|
125
|
-
interface
|
|
126
|
-
|
|
127
|
-
|
|
132
|
+
interface NativeViewGestureHandlerHook {
|
|
133
|
+
/**
|
|
134
|
+
* Called when gesture is in the UNDETERMINED state, shouldActivateOnStart is set to false,
|
|
135
|
+
* and both tryIntercept and wantsToHandleEventBeforeActivation returned false.
|
|
136
|
+
*
|
|
137
|
+
* @return Boolean value signalling whether the handler can transition to the BEGAN state. If false
|
|
138
|
+
* the gesture will be cancelled.
|
|
139
|
+
*/
|
|
140
|
+
fun canBegin() = true
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Called after the gesture transitions to the END state.
|
|
144
|
+
*/
|
|
145
|
+
fun afterGestureEnd(event: MotionEvent) = Unit
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* @return Boolean value signalling whether the gesture can be recognized simultaneously with
|
|
149
|
+
* other (handler). Returning false doesn't necessarily prevent it from happening.
|
|
150
|
+
*/
|
|
151
|
+
fun shouldRecognizeSimultaneously(handler: GestureHandler<*>) = false
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* shouldActivateOnStart and tryIntercept have priority over this method
|
|
155
|
+
*
|
|
156
|
+
* @return Boolean value signalling if the hook wants to handle events passed to the handler
|
|
157
|
+
* before it activates (after that the events are passed to the underlying view).
|
|
158
|
+
*/
|
|
159
|
+
fun wantsToHandleEventBeforeActivation() = false
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Will be called with events if wantsToHandleEventBeforeActivation returns true.
|
|
163
|
+
*/
|
|
164
|
+
fun handleEventBeforeActivation(event: MotionEvent) = Unit
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* @return Boolean value indicating whether the RootViewGestureHandler should be cancelled
|
|
168
|
+
* by this one.
|
|
169
|
+
*/
|
|
170
|
+
fun shouldCancelRootViewGestureHandlerIfNecessary() = false
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
private class EditTextHook(
|
|
174
|
+
private val handler: NativeViewGestureHandler,
|
|
175
|
+
private val editText: ReactEditText
|
|
176
|
+
) : NativeViewGestureHandlerHook {
|
|
177
|
+
private var startX = 0f
|
|
178
|
+
private var startY = 0f
|
|
179
|
+
private var touchSlopSquared: Int
|
|
180
|
+
|
|
181
|
+
init {
|
|
182
|
+
val vc = ViewConfiguration.get(editText.context)
|
|
183
|
+
touchSlopSquared = vc.scaledTouchSlop * vc.scaledTouchSlop
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
override fun afterGestureEnd(event: MotionEvent) {
|
|
187
|
+
if ((event.x - startX) * (event.x - startX) + (event.y - startY) * (event.y - startY) < touchSlopSquared) {
|
|
188
|
+
editText.requestFocusFromJS()
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// recognize alongside every handler besides RootViewGestureHandler, which is a private inner class
|
|
193
|
+
// of RNGestureHandlerRootHelper so no explicit type checks, but its tag is always negative
|
|
194
|
+
// also if other handler is NativeViewGestureHandler then don't override the default implementation
|
|
195
|
+
override fun shouldRecognizeSimultaneously(handler: GestureHandler<*>) =
|
|
196
|
+
handler.tag > 0 && handler !is NativeViewGestureHandler
|
|
197
|
+
|
|
198
|
+
override fun wantsToHandleEventBeforeActivation() = true
|
|
199
|
+
|
|
200
|
+
override fun handleEventBeforeActivation(event: MotionEvent) {
|
|
201
|
+
handler.activate()
|
|
202
|
+
editText.onTouchEvent(event)
|
|
203
|
+
|
|
204
|
+
startX = event.x
|
|
205
|
+
startY = event.y
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
override fun shouldCancelRootViewGestureHandlerIfNecessary() = true
|
|
128
209
|
}
|
|
129
210
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
package com.swmansion.gesturehandler
|
|
2
2
|
|
|
3
3
|
import android.content.Context
|
|
4
|
+
import android.os.Handler
|
|
4
5
|
import android.view.MotionEvent
|
|
5
6
|
import android.view.VelocityTracker
|
|
6
7
|
import android.view.ViewConfiguration
|
|
@@ -40,6 +41,9 @@ class PanGestureHandler(context: Context?) : GestureHandler<PanGestureHandler>()
|
|
|
40
41
|
private var lastY = 0f
|
|
41
42
|
private var velocityTracker: VelocityTracker? = null
|
|
42
43
|
private var averageTouches = false
|
|
44
|
+
private var activateAfterLongPress = DEFAULT_ACTIVATE_AFTER_LONG_PRESS
|
|
45
|
+
private val activateDelayed = Runnable { activate() }
|
|
46
|
+
private var handler: Handler? = null
|
|
43
47
|
|
|
44
48
|
/**
|
|
45
49
|
* On Android when there are multiple pointers on the screen pan gestures most often just consider
|
|
@@ -54,7 +58,7 @@ class PanGestureHandler(context: Context?) : GestureHandler<PanGestureHandler>()
|
|
|
54
58
|
* position of all the fingers will remain still while doing a rotation gesture.
|
|
55
59
|
*/
|
|
56
60
|
init {
|
|
57
|
-
val vc = ViewConfiguration.get(context)
|
|
61
|
+
val vc = ViewConfiguration.get(context!!)
|
|
58
62
|
val touchSlop = vc.scaledTouchSlop
|
|
59
63
|
defaultMinDistSq = (touchSlop * touchSlop).toFloat()
|
|
60
64
|
minDistSq = defaultMinDistSq
|
|
@@ -76,6 +80,7 @@ class PanGestureHandler(context: Context?) : GestureHandler<PanGestureHandler>()
|
|
|
76
80
|
minDistSq = defaultMinDistSq
|
|
77
81
|
minPointers = DEFAULT_MIN_POINTERS
|
|
78
82
|
maxPointers = DEFAULT_MAX_POINTERS
|
|
83
|
+
activateAfterLongPress = DEFAULT_ACTIVATE_AFTER_LONG_PRESS
|
|
79
84
|
averageTouches = false
|
|
80
85
|
}
|
|
81
86
|
|
|
@@ -127,6 +132,10 @@ class PanGestureHandler(context: Context?) : GestureHandler<PanGestureHandler>()
|
|
|
127
132
|
this.averageTouches = averageTouches
|
|
128
133
|
}
|
|
129
134
|
|
|
135
|
+
fun setActivateAfterLongPress(time: Long) = apply {
|
|
136
|
+
this.activateAfterLongPress = time
|
|
137
|
+
}
|
|
138
|
+
|
|
130
139
|
/**
|
|
131
140
|
* @param minVelocity in pixels per second
|
|
132
141
|
*/
|
|
@@ -177,13 +186,18 @@ class PanGestureHandler(context: Context?) : GestureHandler<PanGestureHandler>()
|
|
|
177
186
|
|
|
178
187
|
private fun shouldFail(): Boolean {
|
|
179
188
|
val dx = lastX - startX + offsetX
|
|
189
|
+
val dy = lastY - startY + offsetY
|
|
190
|
+
|
|
191
|
+
if (activateAfterLongPress > 0 && dx * dx + dy * dy > defaultMinDistSq) {
|
|
192
|
+
handler?.removeCallbacksAndMessages(null)
|
|
193
|
+
return true
|
|
194
|
+
}
|
|
180
195
|
if (failOffsetXStart != MAX_VALUE_IGNORE && dx < failOffsetXStart) {
|
|
181
196
|
return true
|
|
182
197
|
}
|
|
183
198
|
if (failOffsetXEnd != MIN_VALUE_IGNORE && dx > failOffsetXEnd) {
|
|
184
199
|
return true
|
|
185
200
|
}
|
|
186
|
-
val dy = lastY - startY + offsetY
|
|
187
201
|
if (failOffsetYStart != MAX_VALUE_IGNORE && dy < failOffsetYStart) {
|
|
188
202
|
return true
|
|
189
203
|
}
|
|
@@ -216,6 +230,13 @@ class PanGestureHandler(context: Context?) : GestureHandler<PanGestureHandler>()
|
|
|
216
230
|
velocityTracker = VelocityTracker.obtain()
|
|
217
231
|
addVelocityMovement(velocityTracker, event)
|
|
218
232
|
begin()
|
|
233
|
+
|
|
234
|
+
if (activateAfterLongPress > 0) {
|
|
235
|
+
if (handler == null) {
|
|
236
|
+
handler = Handler()
|
|
237
|
+
}
|
|
238
|
+
handler!!.postDelayed(activateDelayed, activateAfterLongPress)
|
|
239
|
+
}
|
|
219
240
|
} else if (velocityTracker != null) {
|
|
220
241
|
addVelocityMovement(velocityTracker, event)
|
|
221
242
|
velocityTracker!!.computeCurrentVelocity(1000)
|
|
@@ -257,7 +278,12 @@ class PanGestureHandler(context: Context?) : GestureHandler<PanGestureHandler>()
|
|
|
257
278
|
super.activate(force)
|
|
258
279
|
}
|
|
259
280
|
|
|
281
|
+
override fun onCancel() {
|
|
282
|
+
handler?.removeCallbacksAndMessages(null)
|
|
283
|
+
}
|
|
284
|
+
|
|
260
285
|
override fun onReset() {
|
|
286
|
+
handler?.removeCallbacksAndMessages(null)
|
|
261
287
|
velocityTracker?.let {
|
|
262
288
|
it.recycle()
|
|
263
289
|
velocityTracker = null
|
|
@@ -274,6 +300,7 @@ class PanGestureHandler(context: Context?) : GestureHandler<PanGestureHandler>()
|
|
|
274
300
|
private const val MAX_VALUE_IGNORE = Float.MIN_VALUE
|
|
275
301
|
private const val DEFAULT_MIN_POINTERS = 1
|
|
276
302
|
private const val DEFAULT_MAX_POINTERS = 10
|
|
303
|
+
private const val DEFAULT_ACTIVATE_AFTER_LONG_PRESS = 0L
|
|
277
304
|
|
|
278
305
|
/**
|
|
279
306
|
* This method adds movement to {@class VelocityTracker} first resetting offset of the event so
|