Merge "Add support for stretch overscroll to internal ViewPager" into sc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
72f1c8bca4
@@ -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);
|
||||
@@ -386,6 +386,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.
|
||||
*
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user