react-native-gesture-handler 2.4.0 → 2.5.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|