Skip to content
This repository was archived by the owner on Sep 3, 2024. It is now read-only.

Commit d43377c

Browse files
authored
app/NestedScrollView: fix touch dragging behavior (#34)
Signed-off-by: BlackMesa123 <[email protected]>
1 parent c464092 commit d43377c

File tree

1 file changed

+169
-156
lines changed

1 file changed

+169
-156
lines changed

yanndroid/oneui/src/main/java/de/dlyt/yanndroid/oneui/view/NestedScrollView.java

Lines changed: 169 additions & 156 deletions
Original file line numberDiff line numberDiff line change
@@ -843,64 +843,69 @@ public boolean onGenericMotionEvent(MotionEvent motionEvent) {
843843
}
844844

845845
@SuppressLint("WrongConstant")
846-
public boolean onInterceptTouchEvent(MotionEvent motionEvent) {
847-
int action = motionEvent.getAction();
848-
if (action == 2 && this.mIsBeingDragged) {
846+
public boolean onInterceptTouchEvent(MotionEvent ev) {
847+
final int action = ev.getAction();
848+
if ((action == MotionEvent.ACTION_MOVE) && mIsBeingDragged) {
849849
return true;
850850
}
851-
int i = action & 255;
852-
if (i != 0) {
853-
if (i != 1) {
854-
if (i == 2) {
855-
int i2 = this.mActivePointerId;
856-
if (i2 != -1) {
857-
int findPointerIndex = motionEvent.findPointerIndex(i2);
858-
if (findPointerIndex == -1) {
859-
Log.e(TAG, "Invalid pointerId=" + i2 + " in onInterceptTouchEvent");
860-
} else {
861-
int y = (int) motionEvent.getY(findPointerIndex);
862-
if (Math.abs(y - this.mLastMotionY) > this.mTouchSlop && (2 & getNestedScrollAxes()) == 0) {
863-
this.mIsBeingDragged = true;
864-
this.mLastMotionY = y;
865-
initVelocityTrackerIfNotExists();
866-
this.mVelocityTracker.addMovement(motionEvent);
867-
this.mNestedYOffset = 0;
868-
ViewParent parent = getParent();
869-
if (parent != null) {
870-
parent.requestDisallowInterceptTouchEvent(true);
871-
}
872-
}
873-
}
874-
}
875-
} else if (i != 3) {
876-
if (i == 6) {
877-
onSecondaryPointerUp(motionEvent);
851+
switch (action & MotionEvent.ACTION_MASK) {
852+
case MotionEvent.ACTION_MOVE: {
853+
final int activePointerId = mActivePointerId;
854+
if (activePointerId == INVALID_POINTER) {
855+
break;
856+
}
857+
final int pointerIndex = ev.findPointerIndex(activePointerId);
858+
if (pointerIndex == -1) {
859+
Log.e(TAG, "Invalid pointerId=" + activePointerId + " in onInterceptTouchEvent");
860+
break;
861+
}
862+
final int y = (int) ev.getY(pointerIndex);
863+
final int yDiff = Math.abs(y - mLastMotionY);
864+
if (yDiff > mTouchSlop && (getNestedScrollAxes() & ViewCompat.SCROLL_AXIS_VERTICAL) == 0) {
865+
mIsBeingDragged = true;
866+
mLastMotionY = y;
867+
initVelocityTrackerIfNotExists();
868+
mVelocityTracker.addMovement(ev);
869+
mNestedYOffset = 0;
870+
final ViewParent parent = getParent();
871+
if (parent != null) {
872+
parent.requestDisallowInterceptTouchEvent(true);
878873
}
879874
}
875+
break;
880876
}
881-
this.mIsBeingDragged = false;
882-
this.mActivePointerId = -1;
883-
recycleVelocityTracker();
884-
if (this.mScroller.springBack(getScrollX(), getScrollY(), 0, 0, 0, getScrollRange())) {
885-
ViewCompat.postInvalidateOnAnimation(this);
886-
}
887-
stopNestedScroll(0);
888-
} else {
889-
int y2 = (int) motionEvent.getY();
890-
if (!inChild((int) motionEvent.getX(), y2)) {
891-
this.mIsBeingDragged = false;
892-
recycleVelocityTracker();
893-
} else {
894-
this.mLastMotionY = y2;
895-
this.mActivePointerId = motionEvent.getPointerId(0);
877+
case MotionEvent.ACTION_DOWN: {
878+
final int y = (int) ev.getY();
879+
if (!inChild((int) ev.getX(), y)) {
880+
mIsBeingDragged = !mScroller.isFinished();
881+
recycleVelocityTracker();
882+
break;
883+
}
884+
mLastMotionY = y;
885+
mActivePointerId = ev.getPointerId(0);
896886
initOrResetVelocityTracker();
897-
this.mVelocityTracker.addMovement(motionEvent);
898-
this.mScroller.computeScrollOffset();
899-
this.mIsBeingDragged = !this.mScroller.isFinished();
900-
startNestedScroll(2, 0);
887+
mVelocityTracker.addMovement(ev);
888+
mScroller.computeScrollOffset();
889+
mIsBeingDragged = !mScroller.isFinished();
890+
startNestedScroll(ViewCompat.SCROLL_AXIS_VERTICAL, ViewCompat.TYPE_TOUCH);
891+
break;
901892
}
893+
case MotionEvent.ACTION_CANCEL:
894+
case MotionEvent.ACTION_UP:
895+
mIsBeingDragged = false;
896+
mActivePointerId = INVALID_POINTER;
897+
recycleVelocityTracker();
898+
if (mScroller.springBack(getScrollX(), getScrollY(), 0, 0, 0, getScrollRange())) {
899+
ViewCompat.postInvalidateOnAnimation(this);
900+
}
901+
stopNestedScroll(ViewCompat.TYPE_TOUCH);
902+
break;
903+
case MotionEvent.ACTION_POINTER_UP:
904+
onSecondaryPointerUp(ev);
905+
break;
902906
}
903-
return this.mIsBeingDragged;
907+
908+
return mIsBeingDragged;
904909
}
905910

906911
protected void onLayout(boolean z, int i, int i2, int i3, int i4) {
@@ -1076,127 +1081,135 @@ public void onStopNestedScroll(@NonNull View view, int i) {
10761081
stopNestedScroll(i);
10771082
}
10781083

1079-
@SuppressLint("WrongConstant")
1080-
public boolean onTouchEvent(MotionEvent motionEvent) {
1081-
ViewParent parent;
1084+
public boolean onTouchEvent(MotionEvent ev) {
10821085
initVelocityTrackerIfNotExists();
1083-
int actionMasked = motionEvent.getActionMasked();
1084-
if (actionMasked == 0) {
1085-
this.mNestedYOffset = 0;
1086-
}
1087-
MotionEvent obtain = MotionEvent.obtain(motionEvent);
1088-
obtain.offsetLocation(0.0f, (float) this.mNestedYOffset);
1089-
if (actionMasked != 0) {
1090-
if (actionMasked == 1) {
1091-
VelocityTracker velocityTracker = this.mVelocityTracker;
1092-
velocityTracker.computeCurrentVelocity(1000, (float) this.mMaximumVelocity);
1093-
int yVelocity = (int) velocityTracker.getYVelocity(this.mActivePointerId);
1094-
if (Math.abs(yVelocity) >= this.mMinimumVelocity) {
1095-
int i = -yVelocity;
1096-
float f = (float) i;
1097-
if (!dispatchNestedPreFling(0.0f, f)) {
1098-
dispatchNestedFling(0.0f, f, true);
1099-
fling(i);
1086+
final int actionMasked = ev.getActionMasked();
1087+
if (actionMasked == MotionEvent.ACTION_DOWN) {
1088+
mNestedYOffset = 0;
1089+
}
1090+
MotionEvent vtev = MotionEvent.obtain(ev);
1091+
vtev.offsetLocation(0, mNestedYOffset);
1092+
switch (actionMasked) {
1093+
case MotionEvent.ACTION_DOWN: {
1094+
if (getChildCount() == 0) {
1095+
return false;
1096+
}
1097+
if (mIsBeingDragged) {
1098+
final ViewParent parent = getParent();
1099+
if (parent != null) {
1100+
parent.requestDisallowInterceptTouchEvent(true);
11001101
}
1101-
} else if (this.mScroller.springBack(getScrollX(), getScrollY(), 0, 0, 0, getScrollRange())) {
1102-
ViewCompat.postInvalidateOnAnimation(this);
11031102
}
1104-
this.mActivePointerId = -1;
1105-
endDrag();
1106-
} else if (actionMasked == 2) {
1107-
int findPointerIndex = motionEvent.findPointerIndex(this.mActivePointerId);
1108-
if (findPointerIndex == -1) {
1109-
Log.e(TAG, "Invalid pointerId=" + this.mActivePointerId + " in onTouchEvent");
1110-
} else {
1111-
int y = (int) motionEvent.getY(findPointerIndex);
1112-
int i2 = this.mLastMotionY - y;
1113-
if (!this.mIsBeingDragged && Math.abs(i2) > this.mTouchSlop) {
1114-
ViewParent parent2 = getParent();
1115-
if (parent2 != null) {
1116-
parent2.requestDisallowInterceptTouchEvent(true);
1117-
}
1118-
this.mIsBeingDragged = true;
1119-
i2 = i2 > 0 ? i2 - this.mTouchSlop : i2 + this.mTouchSlop;
1103+
if (!mScroller.isFinished()) {
1104+
abortAnimatedScroll();
1105+
}
1106+
mLastMotionY = (int) ev.getY();
1107+
mActivePointerId = ev.getPointerId(0);
1108+
startNestedScroll(ViewCompat.SCROLL_AXIS_VERTICAL, ViewCompat.TYPE_TOUCH);
1109+
break;
1110+
}
1111+
case MotionEvent.ACTION_MOVE:
1112+
final int activePointerIndex = ev.findPointerIndex(mActivePointerId);
1113+
if (activePointerIndex == -1) {
1114+
Log.e(TAG, "Invalid pointerId=" + mActivePointerId + " in onTouchEvent");
1115+
break;
1116+
}
1117+
final int y = (int) ev.getY(activePointerIndex);
1118+
int deltaY = mLastMotionY - y;
1119+
if (!mIsBeingDragged && Math.abs(deltaY) > mTouchSlop) {
1120+
final ViewParent parent = getParent();
1121+
if (parent != null) {
1122+
parent.requestDisallowInterceptTouchEvent(true);
11201123
}
1121-
int i3 = i2;
1122-
if (this.mIsBeingDragged) {
1123-
if (dispatchNestedPreScroll(0, i3, this.mScrollConsumed, this.mScrollOffset, 0)) {
1124-
i3 -= this.mScrollConsumed[1];
1125-
this.mNestedYOffset += this.mScrollOffset[1];
1126-
}
1127-
this.mLastMotionY = y - this.mScrollOffset[1];
1128-
int scrollY = getScrollY();
1129-
int scrollRange = getScrollRange();
1130-
int overScrollMode = getOverScrollMode();
1131-
boolean z = overScrollMode == 0 || (overScrollMode == 1 && scrollRange > 0);
1132-
if (overScrollByCompat(0, i3, 0, getScrollY(), 0, scrollRange, 0, 0, true) && !hasNestedScrollingParent(0)) {
1133-
this.mVelocityTracker.clear();
1134-
}
1135-
int scrollY2 = getScrollY() - scrollY;
1136-
int i4 = i3 - scrollY2;
1137-
int[] iArr = this.mScrollConsumed;
1138-
iArr[1] = 0;
1139-
dispatchNestedScroll(0, scrollY2, 0, i4, this.mScrollOffset, 0, iArr);
1140-
int i5 = this.mLastMotionY;
1141-
int[] iArr2 = this.mScrollOffset;
1142-
this.mLastMotionY = i5 - iArr2[1];
1143-
this.mNestedYOffset += iArr2[1];
1144-
if (z) {
1145-
int i6 = i3 - this.mScrollConsumed[1];
1146-
ensureGlows();
1147-
int i7 = scrollY + i6;
1148-
if (i7 < 0) {
1149-
EdgeEffectCompat.onPull(this.mEdgeGlowTop, ((float) i6) / ((float) getHeight()), motionEvent.getX(findPointerIndex) / ((float) getWidth()));
1150-
if (!this.mEdgeGlowBottom.isFinished()) {
1151-
this.mEdgeGlowBottom.onRelease();
1152-
}
1153-
} else if (i7 > scrollRange) {
1154-
EdgeEffectCompat.onPull(this.mEdgeGlowBottom, ((float) i6) / ((float) getHeight()), 1.0f - (motionEvent.getX(findPointerIndex) / ((float) getWidth())));
1155-
if (!this.mEdgeGlowTop.isFinished()) {
1156-
this.mEdgeGlowTop.onRelease();
1157-
}
1124+
mIsBeingDragged = true;
1125+
if (deltaY > 0) {
1126+
deltaY -= mTouchSlop;
1127+
} else {
1128+
deltaY += mTouchSlop;
1129+
}
1130+
}
1131+
if (mIsBeingDragged) {
1132+
if (dispatchNestedPreScroll(0, deltaY, mScrollConsumed, mScrollOffset,
1133+
ViewCompat.TYPE_TOUCH)) {
1134+
deltaY -= mScrollConsumed[1];
1135+
mNestedYOffset += mScrollOffset[1];
1136+
}
1137+
1138+
mLastMotionY = y - mScrollOffset[1];
1139+
final int oldY = getScrollY();
1140+
final int range = getScrollRange();
1141+
final int overscrollMode = getOverScrollMode();
1142+
boolean canOverscroll = overscrollMode == View.OVER_SCROLL_ALWAYS || (overscrollMode == View.OVER_SCROLL_IF_CONTENT_SCROLLS && range > 0);
1143+
boolean clearVelocityTracker = overScrollByCompat(0, deltaY, 0, getScrollY(), 0, range, 0, 0, true) && !hasNestedScrollingParent(ViewCompat.TYPE_TOUCH);
1144+
final int scrolledDeltaY = getScrollY() - oldY;
1145+
final int unconsumedY = deltaY - scrolledDeltaY;
1146+
mScrollConsumed[1] = 0;
1147+
dispatchNestedScroll(0, scrolledDeltaY, 0, unconsumedY, mScrollOffset, ViewCompat.TYPE_TOUCH, mScrollConsumed);
1148+
mLastMotionY -= mScrollOffset[1];
1149+
mNestedYOffset += mScrollOffset[1];
1150+
if (canOverscroll) {
1151+
deltaY -= mScrollConsumed[1];
1152+
final int pulledToY = oldY + deltaY;
1153+
if (pulledToY < 0) {
1154+
EdgeEffectCompat.onPull(mEdgeGlowTop, (float) -deltaY / getHeight(), ev.getX(activePointerIndex) / getWidth());
1155+
if (!mEdgeGlowBottom.isFinished()) {
1156+
mEdgeGlowBottom.onRelease();
11581157
}
1159-
SamsungEdgeEffect seslEdgeEffect = this.mEdgeGlowTop;
1160-
if (seslEdgeEffect != null && (!seslEdgeEffect.isFinished() || !this.mEdgeGlowBottom.isFinished())) {
1161-
ViewCompat.postInvalidateOnAnimation(this);
1158+
} else if (pulledToY > range) {
1159+
EdgeEffectCompat.onPull(mEdgeGlowBottom, (float) deltaY / getHeight(), 1.f - ev.getX(activePointerIndex) / getWidth());
1160+
if (!mEdgeGlowTop.isFinished()) {
1161+
mEdgeGlowTop.onRelease();
11621162
}
11631163
}
1164+
if (mEdgeGlowTop != null && (!mEdgeGlowTop.isFinished() || !mEdgeGlowBottom.isFinished())) {
1165+
ViewCompat.postInvalidateOnAnimation(this);
1166+
clearVelocityTracker = false;
1167+
}
1168+
}
1169+
if (clearVelocityTracker) {
1170+
mVelocityTracker.clear();
11641171
}
11651172
}
1166-
} else if (actionMasked == 3) {
1167-
if (this.mIsBeingDragged && getChildCount() > 0 && this.mScroller.springBack(getScrollX(), getScrollY(), 0, 0, 0, getScrollRange())) {
1173+
break;
1174+
case MotionEvent.ACTION_UP:
1175+
final VelocityTracker velocityTracker = mVelocityTracker;
1176+
velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);
1177+
int initialVelocity = (int) velocityTracker.getYVelocity(mActivePointerId);
1178+
if ((Math.abs(initialVelocity) >= mMinimumVelocity)) {
1179+
if (!dispatchNestedPreFling(0, -initialVelocity)) {
1180+
dispatchNestedFling(0, -initialVelocity, true);
1181+
fling(-initialVelocity);
1182+
}
1183+
} else if (mScroller.springBack(getScrollX(), getScrollY(), 0, 0, 0, getScrollRange())) {
11681184
ViewCompat.postInvalidateOnAnimation(this);
11691185
}
1170-
this.mActivePointerId = -1;
1186+
mActivePointerId = INVALID_POINTER;
11711187
endDrag();
1172-
} else if (actionMasked == 5) {
1173-
int actionIndex = motionEvent.getActionIndex();
1174-
this.mLastMotionY = (int) motionEvent.getY(actionIndex);
1175-
this.mActivePointerId = motionEvent.getPointerId(actionIndex);
1176-
} else if (actionMasked == 6) {
1177-
onSecondaryPointerUp(motionEvent);
1178-
this.mLastMotionY = (int) motionEvent.getY(motionEvent.findPointerIndex(this.mActivePointerId));
1179-
}
1180-
} else if (getChildCount() == 0) {
1181-
return false;
1182-
} else {
1183-
boolean z2 = !this.mScroller.isFinished();
1184-
this.mIsBeingDragged = z2;
1185-
if (z2 && (parent = getParent()) != null) {
1186-
parent.requestDisallowInterceptTouchEvent(true);
1187-
}
1188-
if (!this.mScroller.isFinished()) {
1189-
abortAnimatedScroll();
1188+
break;
1189+
case MotionEvent.ACTION_CANCEL:
1190+
if (mIsBeingDragged && getChildCount() > 0) {
1191+
if (mScroller.springBack(getScrollX(), getScrollY(), 0, 0, 0, getScrollRange())) {
1192+
ViewCompat.postInvalidateOnAnimation(this);
1193+
}
1194+
}
1195+
mActivePointerId = INVALID_POINTER;
1196+
endDrag();
1197+
break;
1198+
case MotionEvent.ACTION_POINTER_DOWN: {
1199+
final int index = ev.getActionIndex();
1200+
mLastMotionY = (int) ev.getY(index);
1201+
mActivePointerId = ev.getPointerId(index);
1202+
break;
11901203
}
1191-
this.mLastMotionY = (int) motionEvent.getY();
1192-
this.mActivePointerId = motionEvent.getPointerId(0);
1193-
startNestedScroll(2, 0);
1204+
case MotionEvent.ACTION_POINTER_UP:
1205+
onSecondaryPointerUp(ev);
1206+
mLastMotionY = (int) ev.getY(ev.findPointerIndex(mActivePointerId));
1207+
break;
11941208
}
1195-
VelocityTracker velocityTracker2 = this.mVelocityTracker;
1196-
if (velocityTracker2 != null) {
1197-
velocityTracker2.addMovement(obtain);
1209+
if (mVelocityTracker != null) {
1210+
mVelocityTracker.addMovement(vtev);
11981211
}
1199-
obtain.recycle();
1212+
vtev.recycle();
12001213
return true;
12011214
}
12021215

0 commit comments

Comments
 (0)