Skip to content

Commit

Permalink
fix(android): prevent taps while scrolling (#961)
Browse files Browse the repository at this point in the history
* fix(android): prevent taps while scrolling

* fix: add notifyNativeGestureEnded

brings this more in line with existing react patterns

copied from bluesky-social/social-app@88b1878
  • Loading branch information
gpp-0 authored Jan 20, 2025
1 parent 56a35da commit 16b0ebe
Showing 1 changed file with 20 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import android.view.ViewConfiguration
import android.widget.FrameLayout
import androidx.viewpager2.widget.ViewPager2
import androidx.viewpager2.widget.ViewPager2.ORIENTATION_HORIZONTAL
import com.facebook.react.uimanager.events.NativeGestureUtil
import kotlin.math.absoluteValue
import kotlin.math.sign

Expand All @@ -27,6 +28,7 @@ class NestedScrollableHost : FrameLayout {
private var touchSlop = 0
private var initialX = 0f
private var initialY = 0f
private var nativeGestureStarted: Boolean = false
private val parentViewPager: ViewPager2?
get() {
var v: View? = parent as? View
Expand Down Expand Up @@ -57,17 +59,14 @@ class NestedScrollableHost : FrameLayout {
}

private fun handleInterceptTouchEvent(e: MotionEvent) {
val orientation = parentViewPager?.orientation ?: return

// Early return if child can't scroll in same direction as parent
if (!canChildScroll(orientation, -1f) && !canChildScroll(orientation, 1f)) {
return
}
val orientation = parentViewPager?.orientation

if (e.action == MotionEvent.ACTION_DOWN) {
initialX = e.x
initialY = e.y
parent.requestDisallowInterceptTouchEvent(true)
if (orientation != null) {
parent.requestDisallowInterceptTouchEvent(true)
}
} else if (e.action == MotionEvent.ACTION_MOVE) {
val dx = e.x - initialX
val dy = e.y - initialY
Expand All @@ -78,6 +77,10 @@ class NestedScrollableHost : FrameLayout {
val scaledDy = dy.absoluteValue * if (isVpHorizontal) 1f else .5f

if (scaledDx > touchSlop || scaledDy > touchSlop) {
NativeGestureUtil.notifyNativeGestureStarted(this, e)
nativeGestureStarted = true

if (orientation == null) return
if (isVpHorizontal == (scaledDy > scaledDx)) {
// Gesture is perpendicular, allow all parents to intercept
parent.requestDisallowInterceptTouchEvent(false)
Expand All @@ -94,4 +97,14 @@ class NestedScrollableHost : FrameLayout {
}
}
}

override fun onTouchEvent(e: MotionEvent): Boolean {
if (e.actionMasked == MotionEvent.ACTION_UP) {
if (nativeGestureStarted) {
NativeGestureUtil.notifyNativeGestureEnded(this, e)
nativeGestureStarted = false
}
}
return super.onTouchEvent(e)
}
}

0 comments on commit 16b0ebe

Please sign in to comment.