Loading core/java/android/widget/AbsListView.java +129 −65 Original line number Diff line number Diff line Loading @@ -715,7 +715,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te */ @NonNull @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 123769408) private EdgeEffect mEdgeGlowTop = new EdgeEffect(mContext); private EdgeEffect mEdgeGlowTop; /** * Tracks the state of the bottom edge glow. Loading @@ -725,7 +725,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te */ @NonNull @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 123768444) private EdgeEffect mEdgeGlowBottom = new EdgeEffect(mContext); private EdgeEffect mEdgeGlowBottom; /** * An estimate of how many pixels are between the top of the list and Loading Loading @@ -847,6 +847,8 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te public AbsListView(Context context) { super(context); mEdgeGlowBottom = new EdgeEffect(context); mEdgeGlowTop = new EdgeEffect(context); initAbsListView(); mOwnerThread = Thread.currentThread(); Loading @@ -867,6 +869,8 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te public AbsListView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); mEdgeGlowBottom = new EdgeEffect(context, attrs); mEdgeGlowTop = new EdgeEffect(context, attrs); initAbsListView(); mOwnerThread = Thread.currentThread(); Loading Loading @@ -3584,6 +3588,9 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te mLastY != Integer.MIN_VALUE ? y - mLastY + scrollConsumedCorrection : deltaY; int lastYCorrection = 0; // First allow releasing existing overscroll effect: incrementalDeltaY = releaseGlow(incrementalDeltaY, x); if (mTouchMode == TOUCH_MODE_SCROLL) { if (PROFILE_SCROLLING) { if (!mScrollProfilingStarted) { Loading Loading @@ -3666,14 +3673,14 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te mTouchMode = TOUCH_MODE_OVERSCROLL; } if (incrementalDeltaY > 0) { mEdgeGlowTop.onPull((float) -overscroll / getHeight(), mEdgeGlowTop.onPullDistance((float) -overscroll / getHeight(), (float) x / getWidth()); if (!mEdgeGlowBottom.isFinished()) { mEdgeGlowBottom.onRelease(); } invalidateTopGlow(); } else if (incrementalDeltaY < 0) { mEdgeGlowBottom.onPull((float) overscroll / getHeight(), mEdgeGlowBottom.onPullDistance((float) overscroll / getHeight(), 1.f - (float) x / getWidth()); if (!mEdgeGlowTop.isFinished()) { mEdgeGlowTop.onRelease(); Loading Loading @@ -3713,14 +3720,15 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te (overscrollMode == OVER_SCROLL_IF_CONTENT_SCROLLS && !contentFits())) { if (rawDeltaY > 0) { mEdgeGlowTop.onPull((float) overScrollDistance / getHeight(), mEdgeGlowTop.onPullDistance((float) overScrollDistance / getHeight(), (float) x / getWidth()); if (!mEdgeGlowBottom.isFinished()) { mEdgeGlowBottom.onRelease(); } invalidateTopGlow(); } else if (rawDeltaY < 0) { mEdgeGlowBottom.onPull((float) overScrollDistance / getHeight(), mEdgeGlowBottom.onPullDistance( (float) -overScrollDistance / getHeight(), 1.f - (float) x / getWidth()); if (!mEdgeGlowTop.isFinished()) { mEdgeGlowTop.onRelease(); Loading Loading @@ -3757,6 +3765,44 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te } } /** * If the edge glow is currently active, this consumes part or all of deltaY * on the edge glow. * * @param deltaY The pointer motion, in pixels, in the vertical direction, positive * for moving down and negative for moving up. * @param x The horizontal position of the pointer. * @return The remainder of <code>deltaY</code> that has not been consumed by the * edge glow. */ private int releaseGlow(int deltaY, int x) { // First allow releasing existing overscroll effect: float consumed = 0; if (mEdgeGlowTop.getDistance() != 0) { consumed = mEdgeGlowTop.onPullDistance((float) deltaY / getHeight(), (float) x / getWidth()); if (consumed != 0f) { invalidateTopGlow(); } } else if (mEdgeGlowBottom.getDistance() != 0) { consumed = -mEdgeGlowBottom.onPullDistance((float) -deltaY / getHeight(), 1f - (float) x / getWidth()); if (consumed != 0f) { invalidateBottomGlow(); } } int pixelsConsumed = Math.round(consumed * getHeight()); return deltaY - pixelsConsumed; } /** * @return <code>true</code> if either the top or bottom edge glow is currently active or * <code>false</code> if it has no value to release. */ private boolean isGlowActive() { return mEdgeGlowBottom.getDistance() != 0 || mEdgeGlowTop.getDistance() != 0; } private void invalidateTopGlow() { if (!shouldDisplayEdgeEffects()) { return; Loading Loading @@ -3926,7 +3972,9 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te if (mTouchMode == TOUCH_MODE_OVERFLING) { // Stopped the fling. It is a scroll. if (mFlingRunnable != null) { mFlingRunnable.endFling(); } if (mPositionScroller != null) { mPositionScroller.stop(); } Loading @@ -3936,6 +3984,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te mLastY = mMotionY; mMotionCorrection = 0; mDirection = 0; stopEdgeGlowRecede(ev.getX()); } else { final int x = (int) ev.getX(); final int y = (int) ev.getY(); Loading @@ -3948,7 +3997,10 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te mTouchMode = TOUCH_MODE_SCROLL; mMotionCorrection = 0; motionPosition = findMotionRow(y); if (mFlingRunnable != null) { mFlingRunnable.flywheelTouch(); } stopEdgeGlowRecede(x); } else if ((motionPosition >= 0) && getAdapter().isEnabled(motionPosition)) { // User clicked on an actual view (and was not stopping a // fling). It might be a click or a scroll. Assume it is a Loading Loading @@ -3984,6 +4036,15 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te } } private void stopEdgeGlowRecede(float x) { if (mEdgeGlowTop.getDistance() != 0) { mEdgeGlowTop.onPullDistance(0, x / getWidth()); } if (mEdgeGlowBottom.getDistance() != 0) { mEdgeGlowBottom.onPullDistance(0, x / getWidth()); } } private void onTouchMove(MotionEvent ev, MotionEvent vtev) { if (mHasPerformedLongPress) { // Consume all move events following a successful long press. Loading Loading @@ -4501,7 +4562,10 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te mActivePointerId = ev.getPointerId(0); int motionPosition = findMotionRow(y); if (touchMode != TOUCH_MODE_FLING && motionPosition >= 0) { if (isGlowActive()) { // Pressed during edge effect, so this is considered the same as a fling catch. mTouchMode = TOUCH_MODE_FLING; } else if (touchMode != TOUCH_MODE_FLING && motionPosition >= 0) { // User clicked on an actual view (and was not stopping a fling). // Remember where the motion event started v = getChildAt(motionPosition - mFirstPosition); Loading Loading
core/java/android/widget/AbsListView.java +129 −65 Original line number Diff line number Diff line Loading @@ -715,7 +715,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te */ @NonNull @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 123769408) private EdgeEffect mEdgeGlowTop = new EdgeEffect(mContext); private EdgeEffect mEdgeGlowTop; /** * Tracks the state of the bottom edge glow. Loading @@ -725,7 +725,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te */ @NonNull @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 123768444) private EdgeEffect mEdgeGlowBottom = new EdgeEffect(mContext); private EdgeEffect mEdgeGlowBottom; /** * An estimate of how many pixels are between the top of the list and Loading Loading @@ -847,6 +847,8 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te public AbsListView(Context context) { super(context); mEdgeGlowBottom = new EdgeEffect(context); mEdgeGlowTop = new EdgeEffect(context); initAbsListView(); mOwnerThread = Thread.currentThread(); Loading @@ -867,6 +869,8 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te public AbsListView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); mEdgeGlowBottom = new EdgeEffect(context, attrs); mEdgeGlowTop = new EdgeEffect(context, attrs); initAbsListView(); mOwnerThread = Thread.currentThread(); Loading Loading @@ -3584,6 +3588,9 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te mLastY != Integer.MIN_VALUE ? y - mLastY + scrollConsumedCorrection : deltaY; int lastYCorrection = 0; // First allow releasing existing overscroll effect: incrementalDeltaY = releaseGlow(incrementalDeltaY, x); if (mTouchMode == TOUCH_MODE_SCROLL) { if (PROFILE_SCROLLING) { if (!mScrollProfilingStarted) { Loading Loading @@ -3666,14 +3673,14 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te mTouchMode = TOUCH_MODE_OVERSCROLL; } if (incrementalDeltaY > 0) { mEdgeGlowTop.onPull((float) -overscroll / getHeight(), mEdgeGlowTop.onPullDistance((float) -overscroll / getHeight(), (float) x / getWidth()); if (!mEdgeGlowBottom.isFinished()) { mEdgeGlowBottom.onRelease(); } invalidateTopGlow(); } else if (incrementalDeltaY < 0) { mEdgeGlowBottom.onPull((float) overscroll / getHeight(), mEdgeGlowBottom.onPullDistance((float) overscroll / getHeight(), 1.f - (float) x / getWidth()); if (!mEdgeGlowTop.isFinished()) { mEdgeGlowTop.onRelease(); Loading Loading @@ -3713,14 +3720,15 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te (overscrollMode == OVER_SCROLL_IF_CONTENT_SCROLLS && !contentFits())) { if (rawDeltaY > 0) { mEdgeGlowTop.onPull((float) overScrollDistance / getHeight(), mEdgeGlowTop.onPullDistance((float) overScrollDistance / getHeight(), (float) x / getWidth()); if (!mEdgeGlowBottom.isFinished()) { mEdgeGlowBottom.onRelease(); } invalidateTopGlow(); } else if (rawDeltaY < 0) { mEdgeGlowBottom.onPull((float) overScrollDistance / getHeight(), mEdgeGlowBottom.onPullDistance( (float) -overScrollDistance / getHeight(), 1.f - (float) x / getWidth()); if (!mEdgeGlowTop.isFinished()) { mEdgeGlowTop.onRelease(); Loading Loading @@ -3757,6 +3765,44 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te } } /** * If the edge glow is currently active, this consumes part or all of deltaY * on the edge glow. * * @param deltaY The pointer motion, in pixels, in the vertical direction, positive * for moving down and negative for moving up. * @param x The horizontal position of the pointer. * @return The remainder of <code>deltaY</code> that has not been consumed by the * edge glow. */ private int releaseGlow(int deltaY, int x) { // First allow releasing existing overscroll effect: float consumed = 0; if (mEdgeGlowTop.getDistance() != 0) { consumed = mEdgeGlowTop.onPullDistance((float) deltaY / getHeight(), (float) x / getWidth()); if (consumed != 0f) { invalidateTopGlow(); } } else if (mEdgeGlowBottom.getDistance() != 0) { consumed = -mEdgeGlowBottom.onPullDistance((float) -deltaY / getHeight(), 1f - (float) x / getWidth()); if (consumed != 0f) { invalidateBottomGlow(); } } int pixelsConsumed = Math.round(consumed * getHeight()); return deltaY - pixelsConsumed; } /** * @return <code>true</code> if either the top or bottom edge glow is currently active or * <code>false</code> if it has no value to release. */ private boolean isGlowActive() { return mEdgeGlowBottom.getDistance() != 0 || mEdgeGlowTop.getDistance() != 0; } private void invalidateTopGlow() { if (!shouldDisplayEdgeEffects()) { return; Loading Loading @@ -3926,7 +3972,9 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te if (mTouchMode == TOUCH_MODE_OVERFLING) { // Stopped the fling. It is a scroll. if (mFlingRunnable != null) { mFlingRunnable.endFling(); } if (mPositionScroller != null) { mPositionScroller.stop(); } Loading @@ -3936,6 +3984,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te mLastY = mMotionY; mMotionCorrection = 0; mDirection = 0; stopEdgeGlowRecede(ev.getX()); } else { final int x = (int) ev.getX(); final int y = (int) ev.getY(); Loading @@ -3948,7 +3997,10 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te mTouchMode = TOUCH_MODE_SCROLL; mMotionCorrection = 0; motionPosition = findMotionRow(y); if (mFlingRunnable != null) { mFlingRunnable.flywheelTouch(); } stopEdgeGlowRecede(x); } else if ((motionPosition >= 0) && getAdapter().isEnabled(motionPosition)) { // User clicked on an actual view (and was not stopping a // fling). It might be a click or a scroll. Assume it is a Loading Loading @@ -3984,6 +4036,15 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te } } private void stopEdgeGlowRecede(float x) { if (mEdgeGlowTop.getDistance() != 0) { mEdgeGlowTop.onPullDistance(0, x / getWidth()); } if (mEdgeGlowBottom.getDistance() != 0) { mEdgeGlowBottom.onPullDistance(0, x / getWidth()); } } private void onTouchMove(MotionEvent ev, MotionEvent vtev) { if (mHasPerformedLongPress) { // Consume all move events following a successful long press. Loading Loading @@ -4501,7 +4562,10 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te mActivePointerId = ev.getPointerId(0); int motionPosition = findMotionRow(y); if (touchMode != TOUCH_MODE_FLING && motionPosition >= 0) { if (isGlowActive()) { // Pressed during edge effect, so this is considered the same as a fling catch. mTouchMode = TOUCH_MODE_FLING; } else if (touchMode != TOUCH_MODE_FLING && motionPosition >= 0) { // User clicked on an actual view (and was not stopping a fling). // Remember where the motion event started v = getChildAt(motionPosition - mFirstPosition); Loading