From 382f7cba8dec9b24220e70148f3b53a7a284e7fe Mon Sep 17 00:00:00 2001 From: Graham Mendick Date: Tue, 25 Jun 2024 15:42:39 +0100 Subject: [PATCH] Prevented coordinator intercepting sheet scrolls Couldn't scroll in a bottomsheet or sheet because the coordinator was intercepting it. This interception is a workaround for [a (react native or android?) bug](https://github.com/facebook/react-native/pull/44099) where the nested scroll stops working of scroll content shorter than height. Checked if the event target is a sheet and don't intercept in that case. --- .../reactnative/CoordinatorLayoutView.java | 22 ++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/NavigationReactNative/src/android/src/main/java/com/navigation/reactnative/CoordinatorLayoutView.java b/NavigationReactNative/src/android/src/main/java/com/navigation/reactnative/CoordinatorLayoutView.java index d4139583b4..1735dd855d 100644 --- a/NavigationReactNative/src/android/src/main/java/com/navigation/reactnative/CoordinatorLayoutView.java +++ b/NavigationReactNative/src/android/src/main/java/com/navigation/reactnative/CoordinatorLayoutView.java @@ -97,7 +97,7 @@ ScrollView getScrollView() { public boolean onInterceptTouchEvent(MotionEvent ev) { ScrollView scrollView = getScrollView(); boolean cannotScroll = scrollView != null && scrollView.getScrollY() == 0 && !scrollView.canScrollVertically(1); - if (cannotScroll) { + if (cannotScroll && hitTest(scrollView, this, ev)) { int action = ev.getAction(); switch (action & MotionEvent.ACTION_MASK) { case MotionEvent.ACTION_DOWN: { @@ -147,6 +147,26 @@ public boolean onTouchEvent(MotionEvent ev) { return super.onTouchEvent(ev) || dragging; } + private boolean hitTest(ScrollView scrollView, ViewGroup parent, MotionEvent ev) { + for(int i = parent.getChildCount() - 1; i >= 0; i--) { + View view = parent.getChildAt(i); + int[] childLocation = new int[2]; + view.getLocationOnScreen(childLocation); + float x = ev.getRawX(); + float y = ev.getRawY(); + int childLeft = childLocation[0]; + int childTop = childLocation[1]; + int childRight = childLeft + view.getWidth(); + int childBottom = childTop + view.getHeight(); + if (x >= childLeft && x < childRight && y >= childTop && y < childBottom) { + if (view instanceof BottomSheetView || view instanceof SheetView) return false; + if (view == scrollView) return true; + if (view instanceof ViewGroup viewGroup) return hitTest(scrollView, viewGroup, ev); + } + } + return false; + } + @Override public void addView(View child, int index, ViewGroup.LayoutParams params) { drawingOrderHelper.handleAddView(child);