Track persistent nested Y offset for fling velocity

Track the nested offsets applied persistently in AbsListView and
ScrollView. This allows accurate velocity to be reported to nested
fling/pre-fling.

Bug 17548219

Change-Id: I66199c534aca7fb81746eff6d04c931e4c4e48da
This commit is contained in:
Adam Powell
2014-09-22 09:47:48 -07:00
parent c90b5ebbbf
commit 744beffb6a
2 changed files with 26 additions and 4 deletions

View File

@@ -611,6 +611,12 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
private final int[] mScrollOffset = new int[2];
private final int[] mScrollConsumed = new int[2];
// Used for offsetting MotionEvents that we feed to the VelocityTracker.
// In the future it would be nice to be able to give this to the VelocityTracker
// directly, or alternatively put a VT into absolute-positioning mode that only
// reads the raw screen-coordinate x/y values.
private int mNestedYOffset = 0;
// True when the popup should be hidden because of a call to
// dispatchDisplayHint()
private boolean mPopupHidden;
@@ -3330,6 +3336,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
scrollConsumedCorrection = mScrollConsumed[1];
if (vtev != null) {
vtev.offsetLocation(0, mScrollOffset[1]);
mNestedYOffset += mScrollOffset[1];
}
}
final int deltaY = rawDeltaY;
@@ -3399,6 +3406,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
lastYCorrection -= mScrollOffset[1];
if (vtev != null) {
vtev.offsetLocation(0, mScrollOffset[1]);
mNestedYOffset += mScrollOffset[1];
}
} else {
final boolean atOverscrollEdge = overScrollBy(0, overscroll,
@@ -3582,6 +3590,10 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
final MotionEvent vtev = MotionEvent.obtain(ev);
final int actionMasked = ev.getActionMasked();
if (actionMasked == MotionEvent.ACTION_DOWN) {
mNestedYOffset = 0;
}
vtev.offsetLocation(0, mNestedYOffset);
switch (actionMasked) {
case MotionEvent.ACTION_DOWN: {
onTouchDown(ev);
@@ -4144,7 +4156,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
int action = ev.getAction();
final int actionMasked = ev.getActionMasked();
View v;
if (mPositionScroller != null) {
@@ -4163,7 +4175,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
return true;
}
switch (action & MotionEvent.ACTION_MASK) {
switch (actionMasked) {
case MotionEvent.ACTION_DOWN: {
int touchMode = mTouchMode;
if (touchMode == TOUCH_MODE_OVERFLING || touchMode == TOUCH_MODE_OVERSCROLL) {
@@ -4190,6 +4202,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
mLastY = Integer.MIN_VALUE;
initOrResetVelocityTracker();
mVelocityTracker.addMovement(ev);
mNestedYOffset = 0;
startNestedScroll(SCROLL_AXIS_VERTICAL);
if (touchMode == TOUCH_MODE_FLING) {
return true;

View File

@@ -142,6 +142,7 @@ public class ScrollView extends FrameLayout {
*/
private final int[] mScrollOffset = new int[2];
private final int[] mScrollConsumed = new int[2];
private int mNestedYOffset;
/**
* The StrictMode "critical time span" objects to catch animation
@@ -516,6 +517,7 @@ public class ScrollView extends FrameLayout {
mLastMotionY = y;
initVelocityTrackerIfNotExists();
mVelocityTracker.addMovement(ev);
mNestedYOffset = 0;
if (mScrollStrictSpan == null) {
mScrollStrictSpan = StrictMode.enterCriticalSpan("ScrollView-scroll");
}
@@ -586,9 +588,14 @@ public class ScrollView extends FrameLayout {
MotionEvent vtev = MotionEvent.obtain(ev);
final int action = ev.getAction();
final int actionMasked = ev.getActionMasked();
switch (action & MotionEvent.ACTION_MASK) {
if (actionMasked == MotionEvent.ACTION_DOWN) {
mNestedYOffset = 0;
}
vtev.offsetLocation(0, mNestedYOffset);
switch (actionMasked) {
case MotionEvent.ACTION_DOWN: {
if (getChildCount() == 0) {
return false;
@@ -630,6 +637,7 @@ public class ScrollView extends FrameLayout {
if (dispatchNestedPreScroll(0, deltaY, mScrollConsumed, mScrollOffset)) {
deltaY -= mScrollConsumed[1];
vtev.offsetLocation(0, mScrollOffset[1]);
mNestedYOffset += mScrollOffset[1];
}
if (!mIsBeingDragged && Math.abs(deltaY) > mTouchSlop) {
final ViewParent parent = getParent();
@@ -666,6 +674,7 @@ public class ScrollView extends FrameLayout {
if (dispatchNestedScroll(0, scrolledDeltaY, 0, unconsumedY, mScrollOffset)) {
mLastMotionY -= mScrollOffset[1];
vtev.offsetLocation(0, mScrollOffset[1]);
mNestedYOffset += mScrollOffset[1];
} else if (canOverscroll) {
final int pulledToY = oldY + deltaY;
if (pulledToY < 0) {