Merge "Track motion events before we decide to start scrolling"

This commit is contained in:
Michael Jurka
2011-08-22 16:23:40 -07:00
committed by Android (Google) Code Review
5 changed files with 133 additions and 32 deletions

View File

@@ -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;
}

View File

@@ -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();

View File

@@ -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();

View File

@@ -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) {

View File

@@ -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) {