Skip to content

Commit ebab88e

Browse files
authored
Fix buttons getting stuck in scroll views during overscroll (#3509)
## Description Addresses the issue reported in #3350. Conceptually, it's very similar to the above PR. The main difference is the timing - the above PR cancelled the button during `onReset`, while this one adds `onFail` method (analogous to `onCancel`). This method is called just before the state change, while the timing of `onReset` is dependent on the incoming touch stream and handling of other gestures. With this change, I wasn't able to reproduce the issue anymore, though @latekvo mentioned that he was able to get into a situation where none of `onCancel`, `onFail`, and `onReset` were called. This would likely manifest in the same way, but it looks like an entirely different problem. Here, the gesture was canceled, while the underlying button was still kept as a touch responder, while in the above situation, the gesture would have never finished (or never activated). ## Test plan Tested on the linked reproducer and on the Example app
1 parent 4c18243 commit ebab88e

File tree

2 files changed

+7
-1
lines changed

2 files changed

+7
-1
lines changed

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
@@ -685,6 +685,7 @@ open class GestureHandler<ConcreteGestureHandlerT : GestureHandler<ConcreteGestu
685685

686686
fun fail() {
687687
if (state == STATE_ACTIVE || state == STATE_UNDETERMINED || state == STATE_BEGAN) {
688+
onFail()
688689
moveToState(STATE_FAILED)
689690
}
690691
}
@@ -738,6 +739,7 @@ open class GestureHandler<ConcreteGestureHandlerT : GestureHandler<ConcreteGestu
738739
protected open fun onStateChange(newState: Int, previousState: Int) {}
739740
protected open fun onReset() {}
740741
protected open fun onCancel() {}
742+
protected open fun onFail() {}
741743

742744
private fun isButtonInConfig(clickedButton: Int): Boolean {
743745
if (mouseButton == 0) {

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ class NativeViewGestureHandler : GestureHandler<NativeViewGestureHandler>() {
150150
}
151151
}
152152

153-
override fun onCancel() {
153+
private fun dispatchCancelEventToView() {
154154
val time = SystemClock.uptimeMillis()
155155
val event = MotionEvent.obtain(time, time, MotionEvent.ACTION_CANCEL, 0f, 0f, 0).apply {
156156
action = MotionEvent.ACTION_CANCEL
@@ -159,6 +159,10 @@ class NativeViewGestureHandler : GestureHandler<NativeViewGestureHandler>() {
159159
event.recycle()
160160
}
161161

162+
override fun onCancel() = dispatchCancelEventToView()
163+
164+
override fun onFail() = dispatchCancelEventToView()
165+
162166
override fun onReset() {
163167
this.hook = defaultHook
164168
}

0 commit comments

Comments
 (0)