Skip to content

Commit b3e02c4

Browse files
committed
Fix nested cross-scrolling for ScrollView/HorizontalScrollView
Bug 6429006 Disallow intercepting touch events for parents of ScrollView/HorizontalScrollView when scrolling begins. Properly respect touch slop when the child of a ScrollView does not accept touch events. Change-Id: I2ce503ad5104d450829ed58cd2748c9163e020d3
1 parent fbbdbc2 commit b3e02c4

File tree

2 files changed

+48
-10
lines changed

2 files changed

+48
-10
lines changed

core/java/android/widget/HorizontalScrollView.java

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -536,10 +536,15 @@ public boolean onTouchEvent(MotionEvent ev) {
536536

537537
switch (action & MotionEvent.ACTION_MASK) {
538538
case MotionEvent.ACTION_DOWN: {
539-
mIsBeingDragged = getChildCount() != 0;
540-
if (!mIsBeingDragged) {
539+
if (getChildCount() == 0) {
541540
return false;
542541
}
542+
if ((mIsBeingDragged = !mScroller.isFinished())) {
543+
final ViewParent parent = getParent();
544+
if (parent != null) {
545+
parent.requestDisallowInterceptTouchEvent(true);
546+
}
547+
}
543548

544549
/*
545550
* If being flinged and user touches, stop the fling. isFinished
@@ -555,11 +560,23 @@ public boolean onTouchEvent(MotionEvent ev) {
555560
break;
556561
}
557562
case MotionEvent.ACTION_MOVE:
563+
final int activePointerIndex = ev.findPointerIndex(mActivePointerId);
564+
final int x = (int) ev.getX(activePointerIndex);
565+
int deltaX = mLastMotionX - x;
566+
if (!mIsBeingDragged && Math.abs(deltaX) > mTouchSlop) {
567+
final ViewParent parent = getParent();
568+
if (parent != null) {
569+
parent.requestDisallowInterceptTouchEvent(true);
570+
}
571+
mIsBeingDragged = true;
572+
if (deltaX > 0) {
573+
deltaX -= mTouchSlop;
574+
} else {
575+
deltaX += mTouchSlop;
576+
}
577+
}
558578
if (mIsBeingDragged) {
559579
// Scroll to follow the motion event
560-
final int activePointerIndex = ev.findPointerIndex(mActivePointerId);
561-
final int x = (int) ev.getX(activePointerIndex);
562-
final int deltaX = (int) (mLastMotionX - x);
563580
mLastMotionX = x;
564581

565582
final int oldX = mScrollX;

core/java/android/widget/ScrollView.java

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -482,6 +482,10 @@ public boolean onInterceptTouchEvent(MotionEvent ev) {
482482
if (mScrollStrictSpan == null) {
483483
mScrollStrictSpan = StrictMode.enterCriticalSpan("ScrollView-scroll");
484484
}
485+
final ViewParent parent = getParent();
486+
if (parent != null) {
487+
parent.requestDisallowInterceptTouchEvent(true);
488+
}
485489
}
486490
break;
487491
}
@@ -546,10 +550,15 @@ public boolean onTouchEvent(MotionEvent ev) {
546550

547551
switch (action & MotionEvent.ACTION_MASK) {
548552
case MotionEvent.ACTION_DOWN: {
549-
mIsBeingDragged = getChildCount() != 0;
550-
if (!mIsBeingDragged) {
553+
if (getChildCount() == 0) {
551554
return false;
552555
}
556+
if ((mIsBeingDragged = !mScroller.isFinished())) {
557+
final ViewParent parent = getParent();
558+
if (parent != null) {
559+
parent.requestDisallowInterceptTouchEvent(true);
560+
}
561+
}
553562

554563
/*
555564
* If being flinged and user touches, stop the fling. isFinished
@@ -569,11 +578,23 @@ public boolean onTouchEvent(MotionEvent ev) {
569578
break;
570579
}
571580
case MotionEvent.ACTION_MOVE:
581+
final int activePointerIndex = ev.findPointerIndex(mActivePointerId);
582+
final int y = (int) ev.getY(activePointerIndex);
583+
int deltaY = mLastMotionY - y;
584+
if (!mIsBeingDragged && Math.abs(deltaY) > mTouchSlop) {
585+
final ViewParent parent = getParent();
586+
if (parent != null) {
587+
parent.requestDisallowInterceptTouchEvent(true);
588+
}
589+
mIsBeingDragged = true;
590+
if (deltaY > 0) {
591+
deltaY -= mTouchSlop;
592+
} else {
593+
deltaY += mTouchSlop;
594+
}
595+
}
572596
if (mIsBeingDragged) {
573597
// Scroll to follow the motion event
574-
final int activePointerIndex = ev.findPointerIndex(mActivePointerId);
575-
final int y = (int) ev.getY(activePointerIndex);
576-
final int deltaY = mLastMotionY - y;
577598
mLastMotionY = y;
578599

579600
final int oldX = mScrollX;

0 commit comments

Comments
 (0)