Merge "Track motion events before we decide to start scrolling"
This commit is contained in:
committed by
Android (Google) Code Review
commit
04963769e3
@@ -54,6 +54,7 @@ import android.view.View;
|
||||
import android.view.ViewConfiguration;
|
||||
import android.view.ViewDebug;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.ViewParent;
|
||||
import android.view.ViewTreeObserver;
|
||||
import android.view.accessibility.AccessibilityEvent;
|
||||
import android.view.accessibility.AccessibilityNodeInfo;
|
||||
@@ -2788,7 +2789,10 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
|
||||
reportScrollStateChange(OnScrollListener.SCROLL_STATE_TOUCH_SCROLL);
|
||||
// Time to start stealing events! Once we've stolen them, don't let anyone
|
||||
// steal from us
|
||||
requestDisallowInterceptTouchEvent(true);
|
||||
final ViewParent parent = getParent();
|
||||
if (parent != null) {
|
||||
parent.requestDisallowInterceptTouchEvent(true);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -2848,9 +2852,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
|
||||
View v;
|
||||
int deltaY;
|
||||
|
||||
if (mVelocityTracker == null) {
|
||||
mVelocityTracker = VelocityTracker.obtain();
|
||||
}
|
||||
initVelocityTrackerIfNotExists();
|
||||
mVelocityTracker.addMovement(ev);
|
||||
|
||||
switch (action & MotionEvent.ACTION_MASK) {
|
||||
@@ -2955,7 +2957,10 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
|
||||
// Make sure that we do so in case we're in a parent that can intercept.
|
||||
if ((mGroupFlags & FLAG_DISALLOW_INTERCEPT) == 0 &&
|
||||
Math.abs(deltaY) > mTouchSlop) {
|
||||
requestDisallowInterceptTouchEvent(true);
|
||||
final ViewParent parent = getParent();
|
||||
if (parent != null) {
|
||||
parent.requestDisallowInterceptTouchEvent(true);
|
||||
}
|
||||
}
|
||||
|
||||
final int rawDeltaY = deltaY;
|
||||
@@ -2998,7 +3003,9 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
|
||||
0, mOverscrollDistance, true);
|
||||
if (Math.abs(mOverscrollDistance) == Math.abs(mScrollY)) {
|
||||
// Don't allow overfling if we're at the edge.
|
||||
mVelocityTracker.clear();
|
||||
if (mVelocityTracker != null) {
|
||||
mVelocityTracker.clear();
|
||||
}
|
||||
}
|
||||
|
||||
final int overscrollMode = getOverScrollMode();
|
||||
@@ -3259,10 +3266,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
|
||||
handler.removeCallbacks(mPendingCheckForLongPress);
|
||||
}
|
||||
|
||||
if (mVelocityTracker != null) {
|
||||
mVelocityTracker.recycle();
|
||||
mVelocityTracker = null;
|
||||
}
|
||||
recycleVelocityTracker();
|
||||
|
||||
mActivePointerId = INVALID_POINTER;
|
||||
|
||||
@@ -3307,10 +3311,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
|
||||
handler.removeCallbacks(mPendingCheckForLongPress);
|
||||
}
|
||||
|
||||
if (mVelocityTracker != null) {
|
||||
mVelocityTracker.recycle();
|
||||
mVelocityTracker = null;
|
||||
}
|
||||
recycleVelocityTracker();
|
||||
}
|
||||
|
||||
if (mEdgeGlowTop != null) {
|
||||
@@ -3450,6 +3451,35 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
|
||||
mGlowPaddingRight = rightPadding;
|
||||
}
|
||||
|
||||
private void initOrResetVelocityTracker() {
|
||||
if (mVelocityTracker == null) {
|
||||
mVelocityTracker = VelocityTracker.obtain();
|
||||
} else {
|
||||
mVelocityTracker.clear();
|
||||
}
|
||||
}
|
||||
|
||||
private void initVelocityTrackerIfNotExists() {
|
||||
if (mVelocityTracker == null) {
|
||||
mVelocityTracker = VelocityTracker.obtain();
|
||||
}
|
||||
}
|
||||
|
||||
private void recycleVelocityTracker() {
|
||||
if (mVelocityTracker != null) {
|
||||
mVelocityTracker.recycle();
|
||||
mVelocityTracker = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void requestDisallowInterceptTouchEvent(boolean disallowIntercept) {
|
||||
if (disallowIntercept) {
|
||||
recycleVelocityTracker();
|
||||
}
|
||||
super.requestDisallowInterceptTouchEvent(disallowIntercept);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onInterceptTouchEvent(MotionEvent ev) {
|
||||
int action = ev.getAction();
|
||||
@@ -3487,6 +3517,8 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
|
||||
clearScrollingCache();
|
||||
}
|
||||
mLastY = Integer.MIN_VALUE;
|
||||
initOrResetVelocityTracker();
|
||||
mVelocityTracker.addMovement(ev);
|
||||
if (touchMode == TOUCH_MODE_FLING) {
|
||||
return true;
|
||||
}
|
||||
@@ -3502,6 +3534,8 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
|
||||
mActivePointerId = ev.getPointerId(pointerIndex);
|
||||
}
|
||||
final int y = (int) ev.getY(pointerIndex);
|
||||
initVelocityTrackerIfNotExists();
|
||||
mVelocityTracker.addMovement(ev);
|
||||
if (startScrollIfNeeded(y - mMotionY)) {
|
||||
return true;
|
||||
}
|
||||
@@ -3510,9 +3544,11 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
|
||||
break;
|
||||
}
|
||||
|
||||
case MotionEvent.ACTION_CANCEL:
|
||||
case MotionEvent.ACTION_UP: {
|
||||
mTouchMode = TOUCH_MODE_REST;
|
||||
mActivePointerId = INVALID_POINTER;
|
||||
recycleVelocityTracker();
|
||||
reportScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -399,6 +399,35 @@ public class HorizontalScrollView extends FrameLayout {
|
||||
return false;
|
||||
}
|
||||
|
||||
private void initOrResetVelocityTracker() {
|
||||
if (mVelocityTracker == null) {
|
||||
mVelocityTracker = VelocityTracker.obtain();
|
||||
} else {
|
||||
mVelocityTracker.clear();
|
||||
}
|
||||
}
|
||||
|
||||
private void initVelocityTrackerIfNotExists() {
|
||||
if (mVelocityTracker == null) {
|
||||
mVelocityTracker = VelocityTracker.obtain();
|
||||
}
|
||||
}
|
||||
|
||||
private void recycleVelocityTracker() {
|
||||
if (mVelocityTracker != null) {
|
||||
mVelocityTracker.recycle();
|
||||
mVelocityTracker = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void requestDisallowInterceptTouchEvent(boolean disallowIntercept) {
|
||||
if (disallowIntercept) {
|
||||
recycleVelocityTracker();
|
||||
}
|
||||
super.requestDisallowInterceptTouchEvent(disallowIntercept);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onInterceptTouchEvent(MotionEvent ev) {
|
||||
/*
|
||||
@@ -440,6 +469,8 @@ public class HorizontalScrollView extends FrameLayout {
|
||||
if (xDiff > mTouchSlop) {
|
||||
mIsBeingDragged = true;
|
||||
mLastMotionX = x;
|
||||
initVelocityTrackerIfNotExists();
|
||||
mVelocityTracker.addMovement(ev);
|
||||
if (mParent != null) mParent.requestDisallowInterceptTouchEvent(true);
|
||||
}
|
||||
break;
|
||||
@@ -449,6 +480,7 @@ public class HorizontalScrollView extends FrameLayout {
|
||||
final float x = ev.getX();
|
||||
if (!inChild((int) x, (int) ev.getY())) {
|
||||
mIsBeingDragged = false;
|
||||
recycleVelocityTracker();
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -459,6 +491,9 @@ public class HorizontalScrollView extends FrameLayout {
|
||||
mLastMotionX = x;
|
||||
mActivePointerId = ev.getPointerId(0);
|
||||
|
||||
initOrResetVelocityTracker();
|
||||
mVelocityTracker.addMovement(ev);
|
||||
|
||||
/*
|
||||
* If being flinged and user touches the screen, initiate drag;
|
||||
* otherwise don't. mScroller.isFinished should be false when
|
||||
@@ -498,9 +533,7 @@ public class HorizontalScrollView extends FrameLayout {
|
||||
|
||||
@Override
|
||||
public boolean onTouchEvent(MotionEvent ev) {
|
||||
if (mVelocityTracker == null) {
|
||||
mVelocityTracker = VelocityTracker.obtain();
|
||||
}
|
||||
initVelocityTrackerIfNotExists();
|
||||
mVelocityTracker.addMovement(ev);
|
||||
|
||||
final int action = ev.getAction();
|
||||
@@ -584,11 +617,8 @@ public class HorizontalScrollView extends FrameLayout {
|
||||
|
||||
mActivePointerId = INVALID_POINTER;
|
||||
mIsBeingDragged = false;
|
||||
recycleVelocityTracker();
|
||||
|
||||
if (mVelocityTracker != null) {
|
||||
mVelocityTracker.recycle();
|
||||
mVelocityTracker = null;
|
||||
}
|
||||
if (mEdgeGlowLeft != null) {
|
||||
mEdgeGlowLeft.onRelease();
|
||||
mEdgeGlowRight.onRelease();
|
||||
@@ -602,10 +632,8 @@ public class HorizontalScrollView extends FrameLayout {
|
||||
}
|
||||
mActivePointerId = INVALID_POINTER;
|
||||
mIsBeingDragged = false;
|
||||
if (mVelocityTracker != null) {
|
||||
mVelocityTracker.recycle();
|
||||
mVelocityTracker = null;
|
||||
}
|
||||
recycleVelocityTracker();
|
||||
|
||||
if (mEdgeGlowLeft != null) {
|
||||
mEdgeGlowLeft.onRelease();
|
||||
mEdgeGlowRight.onRelease();
|
||||
|
||||
@@ -408,6 +408,36 @@ public class ScrollView extends FrameLayout {
|
||||
return false;
|
||||
}
|
||||
|
||||
private void initOrResetVelocityTracker() {
|
||||
if (mVelocityTracker == null) {
|
||||
mVelocityTracker = VelocityTracker.obtain();
|
||||
} else {
|
||||
mVelocityTracker.clear();
|
||||
}
|
||||
}
|
||||
|
||||
private void initVelocityTrackerIfNotExists() {
|
||||
if (mVelocityTracker == null) {
|
||||
mVelocityTracker = VelocityTracker.obtain();
|
||||
}
|
||||
}
|
||||
|
||||
private void recycleVelocityTracker() {
|
||||
if (mVelocityTracker != null) {
|
||||
mVelocityTracker.recycle();
|
||||
mVelocityTracker = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void requestDisallowInterceptTouchEvent(boolean disallowIntercept) {
|
||||
if (disallowIntercept) {
|
||||
recycleVelocityTracker();
|
||||
}
|
||||
super.requestDisallowInterceptTouchEvent(disallowIntercept);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean onInterceptTouchEvent(MotionEvent ev) {
|
||||
/*
|
||||
@@ -449,6 +479,8 @@ public class ScrollView extends FrameLayout {
|
||||
if (yDiff > mTouchSlop) {
|
||||
mIsBeingDragged = true;
|
||||
mLastMotionY = y;
|
||||
initVelocityTrackerIfNotExists();
|
||||
mVelocityTracker.addMovement(ev);
|
||||
if (mScrollStrictSpan == null) {
|
||||
mScrollStrictSpan = StrictMode.enterCriticalSpan("ScrollView-scroll");
|
||||
}
|
||||
@@ -460,6 +492,7 @@ public class ScrollView extends FrameLayout {
|
||||
final float y = ev.getY();
|
||||
if (!inChild((int) ev.getX(), (int) y)) {
|
||||
mIsBeingDragged = false;
|
||||
recycleVelocityTracker();
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -470,6 +503,8 @@ public class ScrollView extends FrameLayout {
|
||||
mLastMotionY = y;
|
||||
mActivePointerId = ev.getPointerId(0);
|
||||
|
||||
initOrResetVelocityTracker();
|
||||
mVelocityTracker.addMovement(ev);
|
||||
/*
|
||||
* If being flinged and user touches the screen, initiate drag;
|
||||
* otherwise don't. mScroller.isFinished should be false when
|
||||
@@ -487,6 +522,7 @@ public class ScrollView extends FrameLayout {
|
||||
/* Release the drag */
|
||||
mIsBeingDragged = false;
|
||||
mActivePointerId = INVALID_POINTER;
|
||||
recycleVelocityTracker();
|
||||
if (mScroller.springBack(mScrollX, mScrollY, 0, 0, 0, getScrollRange())) {
|
||||
invalidate();
|
||||
}
|
||||
@@ -505,9 +541,7 @@ public class ScrollView extends FrameLayout {
|
||||
|
||||
@Override
|
||||
public boolean onTouchEvent(MotionEvent ev) {
|
||||
if (mVelocityTracker == null) {
|
||||
mVelocityTracker = VelocityTracker.obtain();
|
||||
}
|
||||
initVelocityTrackerIfNotExists();
|
||||
mVelocityTracker.addMovement(ev);
|
||||
|
||||
final int action = ev.getAction();
|
||||
@@ -1441,10 +1475,7 @@ public class ScrollView extends FrameLayout {
|
||||
private void endDrag() {
|
||||
mIsBeingDragged = false;
|
||||
|
||||
if (mVelocityTracker != null) {
|
||||
mVelocityTracker.recycle();
|
||||
mVelocityTracker = null;
|
||||
}
|
||||
recycleVelocityTracker();
|
||||
|
||||
if (mEdgeGlowTop != null) {
|
||||
mEdgeGlowTop.onRelease();
|
||||
|
||||
@@ -120,6 +120,9 @@ public class RecentsHorizontalScrollView extends HorizontalScrollView
|
||||
}
|
||||
|
||||
public void onBeginDrag(View v) {
|
||||
// We do this so the underlying ScrollView knows that it won't get
|
||||
// the chance to intercept events anymore
|
||||
requestDisallowInterceptTouchEvent(true);
|
||||
}
|
||||
|
||||
public View getChildAtPosition(MotionEvent ev) {
|
||||
|
||||
@@ -135,6 +135,9 @@ public class RecentsVerticalScrollView extends ScrollView implements SwipeHelper
|
||||
}
|
||||
|
||||
public void onBeginDrag(View v) {
|
||||
// We do this so the underlying ScrollView knows that it won't get
|
||||
// the chance to intercept events anymore
|
||||
requestDisallowInterceptTouchEvent(true);
|
||||
}
|
||||
|
||||
public View getChildAtPosition(MotionEvent ev) {
|
||||
|
||||
Reference in New Issue
Block a user