diff options
5 files changed, 133 insertions, 32 deletions
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java index dae118e..86f061a 100644 --- a/core/java/android/widget/AbsListView.java +++ b/core/java/android/widget/AbsListView.java @@ -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; } diff --git a/core/java/android/widget/HorizontalScrollView.java b/core/java/android/widget/HorizontalScrollView.java index b428301..d638732 100644 --- a/core/java/android/widget/HorizontalScrollView.java +++ b/core/java/android/widget/HorizontalScrollView.java @@ -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(); diff --git a/core/java/android/widget/ScrollView.java b/core/java/android/widget/ScrollView.java index e59f731..09c875b 100644 --- a/core/java/android/widget/ScrollView.java +++ b/core/java/android/widget/ScrollView.java @@ -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(); diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsHorizontalScrollView.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsHorizontalScrollView.java index 36f1659..8da2db6 100644 --- a/packages/SystemUI/src/com/android/systemui/recent/RecentsHorizontalScrollView.java +++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsHorizontalScrollView.java @@ -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) { diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsVerticalScrollView.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsVerticalScrollView.java index 959328f..b1a30d9 100644 --- a/packages/SystemUI/src/com/android/systemui/recent/RecentsVerticalScrollView.java +++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsVerticalScrollView.java @@ -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) { |