summaryrefslogtreecommitdiff
path: root/core/java
diff options
context:
space:
mode:
authorTreeHugger Robot <treehugger-gerrit@google.com>2021-03-19 21:15:34 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2021-03-19 21:15:34 +0000
commit72f1c8bca41af21a4308f69f3c8e6339a5dc0213 (patch)
tree606e50dd9c3c5b6de1c324f041a104a02a2992dc /core/java
parente463f4c1513683bd648459608013587df7794895 (diff)
parent13cdf67f8a70242d7a422c76fbbb96a78ca26dc3 (diff)
Merge "Add support for stretch overscroll to internal ViewPager" into sc-dev
Diffstat (limited to 'core/java')
-rw-r--r--core/java/com/android/internal/widget/ViewPager.java84
1 files changed, 75 insertions, 9 deletions
diff --git a/core/java/com/android/internal/widget/ViewPager.java b/core/java/com/android/internal/widget/ViewPager.java
index 6f377b9b228a..93cde3ddb72d 100644
--- a/core/java/com/android/internal/widget/ViewPager.java
+++ b/core/java/com/android/internal/widget/ViewPager.java
@@ -353,8 +353,8 @@ public class ViewPager extends ViewGroup {
mTouchSlop = configuration.getScaledPagingTouchSlop();
mMinimumVelocity = (int) (MIN_FLING_VELOCITY * density);
mMaximumVelocity = configuration.getScaledMaximumFlingVelocity();
- mLeftEdge = new EdgeEffect(context);
- mRightEdge = new EdgeEffect(context);
+ mLeftEdge = new EdgeEffect(context, attrs);
+ mRightEdge = new EdgeEffect(context, attrs);
mFlingDistance = (int) (MIN_DISTANCE_FOR_FLING * density);
mCloseEnough = (int) (CLOSE_ENOUGH * density);
@@ -387,6 +387,28 @@ public class ViewPager extends ViewGroup {
}
/**
+ * Returns the {@link EdgeEffect#getType()} for the edge effects.
+ * @return the {@link EdgeEffect#getType()} for the edge effects.
+ * @attr ref android.R.styleable#EdgeEffect_edgeEffectType
+ */
+ @EdgeEffect.EdgeEffectType
+ public int getEdgeEffectType() {
+ // Both left and right edge have the same edge effect type
+ return mLeftEdge.getType();
+ }
+
+ /**
+ * Sets the {@link EdgeEffect#setType(int)} for the edge effects.
+ * @param type The edge effect type to use for the edge effects.
+ * @attr ref android.R.styleable#EdgeEffect_edgeEffectType
+ */
+ public void setEdgeEffectType(@EdgeEffect.EdgeEffectType int type) {
+ mLeftEdge.setType(type);
+ mRightEdge.setType(type);
+ invalidate();
+ }
+
+ /**
* Set a PagerAdapter that will supply views for this pager as needed.
*
* @param adapter Adapter to use
@@ -1891,7 +1913,7 @@ public class ViewPager extends ViewGroup {
}
if (mIsBeingDragged) {
// Scroll to follow the motion event
- if (performDrag(x)) {
+ if (performDrag(x, y)) {
postInvalidateOnAnimation();
}
}
@@ -1918,6 +1940,17 @@ public class ViewPager extends ViewGroup {
mIsBeingDragged = true;
requestParentDisallowInterceptTouchEvent(true);
setScrollState(SCROLL_STATE_DRAGGING);
+ } else if (mLeftEdge.getDistance() != 0
+ || mRightEdge.getDistance() != 0) {
+ // Caught the edge glow animation
+ mIsBeingDragged = true;
+ setScrollState(SCROLL_STATE_DRAGGING);
+ if (mLeftEdge.getDistance() != 0) {
+ mLeftEdge.onPullDistance(0f, 1 - mLastMotionY / getHeight());
+ }
+ if (mRightEdge.getDistance() != 0) {
+ mRightEdge.onPullDistance(0f, mLastMotionY / getHeight());
+ }
} else {
completeScroll(false);
mIsBeingDragged = false;
@@ -2009,7 +2042,7 @@ public class ViewPager extends ViewGroup {
// Scroll to follow the motion event
final int activePointerIndex = ev.findPointerIndex(mActivePointerId);
final float x = ev.getX(activePointerIndex);
- needsInvalidate |= performDrag(x);
+ needsInvalidate |= performDrag(x, ev.getY(activePointerIndex));
}
break;
case MotionEvent.ACTION_UP:
@@ -2080,12 +2113,43 @@ public class ViewPager extends ViewGroup {
}
}
- private boolean performDrag(float x) {
+ /**
+ * If either of the horizontal edge glows are currently active, this consumes part or all of
+ * deltaX on the edge glow.
+ *
+ * @param deltaX The pointer motion, in pixels, in the horizontal direction, positive
+ * for moving down and negative for moving up.
+ * @param y The vertical position of the pointer.
+ * @return The amount of <code>deltaX</code> that has been consumed by the
+ * edge glow.
+ */
+ private float releaseHorizontalGlow(float deltaX, float y) {
+ // First allow releasing existing overscroll effect:
+ float consumed = 0;
+ float displacement = y / getHeight();
+ float pullDistance = (float) deltaX / getWidth();
+ if (mLeftEdge.getDistance() != 0) {
+ consumed = -mLeftEdge.onPullDistance(-pullDistance, 1 - displacement);
+ } else if (mRightEdge.getDistance() != 0) {
+ consumed = mRightEdge.onPullDistance(pullDistance, displacement);
+ }
+ return consumed * getWidth();
+ }
+
+ private boolean performDrag(float x, float y) {
boolean needsInvalidate = false;
+ final float dX = mLastMotionX - x;
final int width = getPaddedWidth();
- final float deltaX = mLastMotionX - x;
mLastMotionX = x;
+ final float releaseConsumed = releaseHorizontalGlow(dX, y);
+ final float deltaX = dX - releaseConsumed;
+ if (releaseConsumed != 0) {
+ needsInvalidate = true;
+ }
+ if (Math.abs(deltaX) < 0.0001f) { // ignore rounding errors from releaseHorizontalGlow()
+ return needsInvalidate;
+ }
final EdgeEffect startEdge;
final EdgeEffect endEdge;
@@ -2128,14 +2192,14 @@ public class ViewPager extends ViewGroup {
if (scrollStart < startBound) {
if (startAbsolute) {
final float over = startBound - scrollStart;
- startEdge.onPull(Math.abs(over) / width);
+ startEdge.onPullDistance(over / width, 1 - y / getHeight());
needsInvalidate = true;
}
clampedScrollStart = startBound;
} else if (scrollStart > endBound) {
if (endAbsolute) {
final float over = scrollStart - endBound;
- endEdge.onPull(Math.abs(over) / width);
+ endEdge.onPullDistance(over / width, y / getHeight());
needsInvalidate = true;
}
clampedScrollStart = endBound;
@@ -2228,7 +2292,9 @@ public class ViewPager extends ViewGroup {
*/
private int determineTargetPage(int currentPage, float pageOffset, int velocity, int deltaX) {
int targetPage;
- if (Math.abs(deltaX) > mFlingDistance && Math.abs(velocity) > mMinimumVelocity) {
+ if (Math.abs(deltaX) > mFlingDistance && Math.abs(velocity) > mMinimumVelocity
+ && mLeftEdge.getDistance() == 0 // don't fling while stretched
+ && mRightEdge.getDistance() == 0) {
targetPage = currentPage - (velocity < 0 ? mLeftIncr : 0);
} else {
final float truncator = currentPage >= mCurItem ? 0.4f : 0.6f;