summaryrefslogtreecommitdiffstats
path: root/src/com/cyanogenmod/trebuchet/PagedView.java
diff options
context:
space:
mode:
authornebkat <nebkat@teamhacksung.org>2012-04-08 13:32:55 +0200
committernebkat <nebkat@teamhacksung.org>2012-12-16 12:05:21 +0000
commitced2e4fce571d48bb7e13af6c95b2f3e851ec51b (patch)
tree91e68f99409e6fc8fd44aeee49915bc6afc709d3 /src/com/cyanogenmod/trebuchet/PagedView.java
parent4f021e98a81c1cef15c7fd5733cc4e16a4c2a8ef (diff)
downloadandroid_packages_apps_Trebuchet-ced2e4fce571d48bb7e13af6c95b2f3e851ec51b.tar.gz
android_packages_apps_Trebuchet-ced2e4fce571d48bb7e13af6c95b2f3e851ec51b.tar.bz2
android_packages_apps_Trebuchet-ced2e4fce571d48bb7e13af6c95b2f3e851ec51b.zip
PagedView: Vertical
Change-Id: Ifed3f713da1f482e67d22765a6215e7d194194eb Conflicts: src/com/cyanogenmod/trebuchet/Workspace.java
Diffstat (limited to 'src/com/cyanogenmod/trebuchet/PagedView.java')
-rw-r--r--src/com/cyanogenmod/trebuchet/PagedView.java543
1 files changed, 389 insertions, 154 deletions
diff --git a/src/com/cyanogenmod/trebuchet/PagedView.java b/src/com/cyanogenmod/trebuchet/PagedView.java
index ec4a5fa00..aa745217f 100644
--- a/src/com/cyanogenmod/trebuchet/PagedView.java
+++ b/src/com/cyanogenmod/trebuchet/PagedView.java
@@ -82,23 +82,31 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
protected int mMinFlingVelocity;
protected int mMinSnapVelocity;
+ // Vertical paged view
+ protected boolean mVertical;
+
protected float mDensity;
protected float mSmoothingTime;
protected float mTouchX;
+ protected float mTouchY;
protected boolean mFirstLayout = true;
protected int mCurrentPage;
protected int mNextPage = INVALID_PAGE;
protected int mMaxScrollX;
+ protected int mMaxScrollY;
protected Scroller mScroller;
private VelocityTracker mVelocityTracker;
private float mDownMotionX;
+ private float mDownMotionY;
protected float mLastMotionX;
protected float mLastMotionXRemainder;
protected float mLastMotionY;
+ protected float mLastMotionYRemainder;
protected float mTotalMotionX;
+ protected float mTotalMotionY;
private int mLastScreenScroll = -1;
private int[] mChildOffsets;
private int[] mChildRelativeOffsets;
@@ -121,6 +129,7 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
private int mPagingTouchSlop;
private int mMaximumVelocity;
private int mMinimumWidth;
+ private int mMinimumHeight;
protected int mPageSpacing;
protected int mPageLayoutPaddingTop;
protected int mPageLayoutPaddingBottom;
@@ -130,9 +139,10 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
protected int mPageLayoutHeightGap;
protected int mCellCountX = 0;
protected int mCellCountY = 0;
- protected boolean mCenterPagesVertically;
+ protected boolean mCenterPages;
protected boolean mAllowOverScroll = true;
protected int mUnboundedScrollX;
+ protected int mUnboundedScrollY;
protected int[] mTempVisiblePagesRange = new int[2];
protected boolean mForceDrawAllChildrenNextFrame;
@@ -140,6 +150,7 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
// it is equal to the scaled overscroll position. We use a separate value so as to prevent
// the screens from continuing to translate beyond the normal bounds.
protected int mOverScrollX;
+ protected int mOverScrollY;
// parameter that adjusts the layout to be optimized for pages with that scale factor
protected float mLayoutScale = 1.0f;
@@ -239,7 +250,8 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
mDirtyPageContent.ensureCapacity(32);
mScroller = new Scroller(getContext(), getScrollInterpolator());
mCurrentPage = 0;
- mCenterPagesVertically = true;
+ mVertical = false;
+ mCenterPages = true;
final ViewConfiguration configuration = ViewConfiguration.get(getContext());
mTouchSlop = configuration.getScaledTouchSlop();
@@ -301,11 +313,13 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
* the previous tab page.
*/
protected void updateCurrentPageScroll() {
- int offset = getChildOffset(mCurrentPage);
- int relOffset = getRelativeChildOffset(mCurrentPage);
- int newX = offset - relOffset;
- scrollTo(newX, 0);
- mScroller.setFinalX(newX);
+ int newXY = getChildOffset(mCurrentPage) - getRelativeChildOffset(mCurrentPage);
+ scrollTo(!mVertical ? newXY : 0, mVertical ? newXY : 0);
+ if (!mVertical) {
+ mScroller.setFinalX(newXY);
+ } else {
+ mScroller.setFinalY(newXY);
+ }
mScroller.forceFinished(true);
}
@@ -396,29 +410,47 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
@Override
public void scrollBy(int x, int y) {
- scrollTo(mUnboundedScrollX + x, getScrollY() + y);
+ scrollTo((!mVertical ? mUnboundedScrollX : mScrollX) + x, (mVertical ? mUnboundedScrollY : mScrollY) + y);
}
@Override
public void scrollTo(int x, int y) {
mUnboundedScrollX = x;
+ mUnboundedScrollY = y;
- if (x < 0) {
- super.scrollTo(0, y);
- if (mAllowOverScroll) {
- overScroll(x);
- }
- } else if (x > mMaxScrollX) {
- super.scrollTo(mMaxScrollX, y);
- if (mAllowOverScroll) {
- overScroll(x - mMaxScrollX);
+ if (!mVertical) {
+ if (x < 0) {
+ super.scrollTo(0, y);
+ if (mAllowOverScroll) {
+ overScroll(x);
+ }
+ } else if (x > mMaxScrollX) {
+ super.scrollTo(mMaxScrollX, y);
+ if (mAllowOverScroll) {
+ overScroll(x - mMaxScrollX);
+ }
+ } else {
+ mOverScrollX = x;
+ super.scrollTo(x, y);
}
} else {
- mOverScrollX = x;
- super.scrollTo(x, y);
+ if (y < 0) {
+ super.scrollTo(x, 0);
+ if (mAllowOverScroll) {
+ overScroll(y);
+ }
+ } else if (y > mMaxScrollY) {
+ super.scrollTo(x, mMaxScrollY);
+ if (mAllowOverScroll) {
+ overScroll(y - mMaxScrollY);
+ }
+ } else {
+ mOverScrollY = y;
+ super.scrollTo(x, y);
+ }
}
-
mTouchX = x;
+ mTouchY = y;
mSmoothingTime = System.nanoTime() / NANOTIME_DIV;
}
@@ -477,25 +509,23 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
}
final int widthMode = MeasureSpec.getMode(widthMeasureSpec);
- final int widthSize = MeasureSpec.getSize(widthMeasureSpec);
final int heightMode = MeasureSpec.getMode(heightMeasureSpec);
+ int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
- if (widthMode != MeasureSpec.EXACTLY) {
- throw new IllegalStateException("Workspace can only be used in EXACTLY mode.");
- }
-
// Return early if we aren't given a proper dimension
if (widthSize <= 0 || heightSize <= 0) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
return;
}
+ if (!mVertical && widthMode != MeasureSpec.EXACTLY) {
+ throw new IllegalStateException("Workspace can only be used in EXACTLY mode.");
+ }
+ if (mVertical && heightMode != MeasureSpec.EXACTLY) {
+ throw new IllegalStateException("Workspace can only be used in EXACTLY mode.");
+ }
- /* Allow the height to be set as WRAP_CONTENT. This allows the particular case
- * of the All apps view on XLarge displays to not take up more space then it needs. Width
- * is still not allowed to be set as WRAP_CONTENT since many parts of the code expect
- * each page to have the same width.
- */
int maxChildHeight = 0;
+ int maxChildWidth = 0;
final int verticalPadding = getPaddingTop() + getPaddingBottom();
final int horizontalPadding = getPaddingLeft() + getPaddingRight();
@@ -531,12 +561,15 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
maxChildHeight = Math.max(maxChildHeight, child.getMeasuredHeight());
+ maxChildWidth = Math.max(maxChildWidth, child.getMeasuredWidth());
if (DEBUG) Log.d(TAG, "\tmeasure-child" + i + ": " + child.getMeasuredWidth() + ", "
+ child.getMeasuredHeight());
}
- if (heightMode == MeasureSpec.AT_MOST) {
+ if (!mVertical && heightMode == MeasureSpec.AT_MOST) {
heightSize = maxChildHeight + verticalPadding;
+ } else if (mVertical && widthMode == MeasureSpec.AT_MOST) {
+ widthSize = maxChildWidth + horizontalPadding;
}
setMeasuredDimension(widthSize, heightSize);
@@ -566,20 +599,24 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
updateScrollingIndicatorPosition();
if (childCount > 0) {
- mMaxScrollX = getChildOffset(childCount - 1) - getRelativeChildOffset(childCount - 1);
+ mMaxScrollX = mMaxScrollY = getChildOffset(childCount - 1) - getRelativeChildOffset(childCount - 1);
} else {
- mMaxScrollX = 0;
+ mMaxScrollX = mMaxScrollY = 0;
}
}
protected void scrollToNewPageWithoutMovingPages(int newCurrentPage) {
- int newX = getChildOffset(newCurrentPage) - getRelativeChildOffset(newCurrentPage);
- int delta = newX - getScrollX();
+ int newXY = getChildOffset(newCurrentPage) - getRelativeChildOffset(newCurrentPage);
+ int delta = newXY - (!mVertical ? mScrollX : mScrollY);
final int pageCount = getChildCount();
for (int i = 0; i < pageCount; i++) {
- View page = (View) getPageAt(i);
- page.setX(page.getX() + delta);
+ View page = getPageAt(i);
+ if (!mVertical) {
+ page.setX(page.getX() + delta);
+ } else {
+ page.setY(page.getY() + delta);
+ }
}
setCurrentPage(newCurrentPage);
}
@@ -629,31 +666,75 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
}
if (DEBUG) Log.d(TAG, "PagedView.onLayout()");
- final int verticalPadding = getPaddingTop() + getPaddingBottom();
+ final int verticalPadding = mPaddingTop + mPaddingBottom;
+ final int horizontalPadding = mPaddingLeft + mPaddingRight;
final int childCount = getChildCount();
- int childLeft = getRelativeChildOffset(0);
+ int childLeft = 0;
+ int childTop = 0;
+ if (childCount > 0) {
+ if (DEBUG) Log.d(TAG, "getRelativeChildOffset(): " + getMeasuredWidth() + ", "
+ + getChildWidth(0));
+
+ if (!mVertical) {
+ childLeft = getRelativeChildOffset(0);
+ } else {
+ childTop = getRelativeChildOffset(0);
+ }
+
+ // Calculate the variable page spacing if necessary
+ if (mPageSpacing < 0) {
+ if (!mVertical) {
+ setPageSpacing(((right - left) - getChildAt(0).getMeasuredWidth()) / 2);
+ } else {
+ setPageSpacing(((top - bottom) - getChildAt(0).getMeasuredHeight()) / 2);
+ }
+ }
+ }
for (int i = 0; i < childCount; i++) {
final View child = getPageAt(i);
if (child.getVisibility() != View.GONE) {
- final int childWidth = getScaledMeasuredWidth(child);
- final int childHeight = child.getMeasuredHeight();
- int childTop = getPaddingTop();
- if (mCenterPagesVertically) {
- childTop += ((getMeasuredHeight() - verticalPadding) - childHeight) / 2;
+ final int childWidth = !mVertical ? getScaledMeasuredWidth(child) : child.getMeasuredWidth();
+ final int childHeight = mVertical ? getScaledMeasuredHeight(child) : child.getMeasuredHeight();
+ if (!mVertical) {
+ childTop = mPaddingTop;
+ } else {
+ childLeft = mPaddingLeft;
+ }
+
+ if (mCenterPages) {
+ if (!mVertical) {
+ childTop += ((getMeasuredHeight() - verticalPadding) - childHeight) / 2;
+ } else {
+ childLeft += ((getMeasuredWidth() - horizontalPadding) - childWidth) / 2;
+ }
}
if (DEBUG) Log.d(TAG, "\tlayout-child" + i + ": " + childLeft + ", " + childTop);
child.layout(childLeft, childTop,
- childLeft + child.getMeasuredWidth(), childTop + childHeight);
- childLeft += childWidth + mPageSpacing;
+ childLeft + (!mVertical ? child.getMeasuredWidth() : childWidth),
+ childTop + (mVertical ? child.getMeasuredHeight() : childHeight));
+ if (!mVertical) {
+ childLeft += childWidth + mPageSpacing;
+ } else {
+ childTop += childHeight + mPageSpacing;
+ }
}
}
if (mFirstLayout && mCurrentPage >= 0 && mCurrentPage < getChildCount()) {
- setHorizontalScrollBarEnabled(false);
- updateCurrentPageScroll();
- setHorizontalScrollBarEnabled(true);
+ int newXY = getChildOffset(mCurrentPage) - getRelativeChildOffset(mCurrentPage);
+ if (!mVertical) {
+ setHorizontalScrollBarEnabled(false);
+ scrollTo(newXY, 0);
+ mScroller.setFinalX(newXY);
+ setHorizontalScrollBarEnabled(true);
+ } else {
+ setVerticalScrollBarEnabled(false);
+ scrollTo(0, newXY);
+ mScroller.setFinalY(newXY);
+ setVerticalScrollBarEnabled(true);
+ }
mFirstLayout = false;
}
}
@@ -721,7 +802,8 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
int offset = getRelativeChildOffset(0);
for (int i = 0; i < index; ++i) {
- offset += getScaledMeasuredWidth(getPageAt(i)) + mPageSpacing;
+ offset += (!mVertical ? getScaledMeasuredWidth(getPageAt(i)) :
+ getScaledMeasuredHeight(getPageAt(i))) + mPageSpacing;
}
if (childOffsets != null) {
childOffsets[index] = offset;
@@ -734,9 +816,16 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
if (mChildRelativeOffsets != null && mChildRelativeOffsets[index] != -1) {
return mChildRelativeOffsets[index];
} else {
- final int padding = getPaddingLeft() + getPaddingRight();
- final int offset = getPaddingLeft() +
- (getMeasuredWidth() - padding - getChildWidth(index)) / 2;
+ int offset;
+ if (!mVertical) {
+ final int padding = mPaddingLeft + mPaddingRight;
+ offset = mPaddingLeft +
+ (getMeasuredWidth() - padding - getChildWidth(index)) / 2;
+ } else {
+ final int padding = mPaddingTop + mPaddingBottom;
+ offset = mPaddingTop +
+ (getMeasuredHeight() - padding - getChildHeight(index)) / 2;
+ }
if (mChildRelativeOffsets != null) {
mChildRelativeOffsets[index] = offset;
}
@@ -744,6 +833,20 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
}
}
+ protected int getScaledRelativeChildOffset(int index) {
+ int offset;
+ if (!mVertical) {
+ final int padding = mPaddingLeft + mPaddingRight;
+ offset = mPaddingLeft + (getMeasuredWidth() - padding -
+ getScaledMeasuredWidth(getPageAt(index))) / 2;
+ } else {
+ final int padding = mPaddingTop + mPaddingBottom;
+ offset = mPaddingTop + (getMeasuredHeight() - padding -
+ getScaledMeasuredHeight(getPageAt(index))) / 2;
+ }
+ return offset;
+ }
+
protected int getScaledMeasuredWidth(View child) {
// This functions are called enough times that it actually makes a difference in the
// profiler -- so just inline the max() here
@@ -753,29 +856,56 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
return (int) (maxWidth * mLayoutScale + 0.5f);
}
+ protected int getScaledMeasuredHeight(View child) {
+ // This functions are called enough times that it actually makes a difference in the
+ // profiler -- so just inline the max() here
+ final int measuredHeight = child.getMeasuredHeight();
+ final int minHeight = mMinimumHeight;
+ final int maxHeight = (minHeight > measuredHeight) ? minHeight : measuredHeight;
+ return (int) (maxHeight * mLayoutScale + 0.5f);
+ }
+
protected void getVisiblePages(int[] range) {
final int pageCount = getChildCount();
if (pageCount > 0) {
- final int screenWidth = getMeasuredWidth();
- int leftScreen = 0;
- int rightScreen = 0;
- View currPage = getPageAt(leftScreen);
- while (leftScreen < pageCount - 1 &&
- currPage.getX() + currPage.getWidth() -
- currPage.getPaddingRight() < getScrollX()) {
- leftScreen++;
- currPage = getPageAt(leftScreen);
- }
- rightScreen = leftScreen;
- currPage = getPageAt(rightScreen + 1);
- while (rightScreen < pageCount - 1 &&
- currPage.getX() - currPage.getPaddingLeft() < getScrollX() + screenWidth) {
- rightScreen++;
- currPage = getPageAt(rightScreen + 1);
+ if (!mVertical) {
+ final int pageWidth = getScaledMeasuredWidth(getPageAt(0));
+ final int screenWidth = getMeasuredWidth();
+ int x = getScaledRelativeChildOffset(0) + pageWidth;
+ int leftScreen = 0;
+ int rightScreen = 0;
+ while (x <= mScrollX && leftScreen < pageCount - 1) {
+ leftScreen++;
+ x += getScaledMeasuredWidth(getPageAt(leftScreen)) + mPageSpacing;
+ }
+ rightScreen = leftScreen;
+
+
+ while (x < mScrollX + screenWidth && rightScreen < pageCount - 1) {
+ rightScreen++;
+ x += getScaledMeasuredWidth(getPageAt(rightScreen)) + mPageSpacing;
+ }
+ range[0] = leftScreen;
+ range[1] = rightScreen;
+ } else {
+ final int pageHeight = getScaledMeasuredHeight(getPageAt(0));
+ final int screenHeight = getMeasuredHeight();
+ int y = getScaledRelativeChildOffset(0) + pageHeight;
+ int topScreen = 0;
+ int bottomScreen = 0;
+ while (y <= mScrollY && topScreen < pageCount - 1) {
+ topScreen++;
+ y += getScaledMeasuredHeight(getPageAt(topScreen)) + mPageSpacing;
+ }
+ bottomScreen = topScreen;
+ while (y < mScrollY + screenHeight && bottomScreen < pageCount - 1) {
+ bottomScreen++;
+ y += getScaledMeasuredHeight(getPageAt(bottomScreen)) + mPageSpacing;
+ }
+ range[0] = topScreen;
+ range[1] = bottomScreen;
}
- range[0] = leftScreen;
- range[1] = rightScreen;
} else {
range[0] = -1;
range[1] = -1;
@@ -788,21 +918,27 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
@Override
protected void dispatchDraw(Canvas canvas) {
- if (mOverScrollX != mLastScreenScroll || mForceScreenScrolled) {
- // set mForceScreenScrolled before calling screenScrolled so that screenScrolled can
- // set it for the next frame
- mForceScreenScrolled = false;
- screenScrolled(mOverScrollX);
- mLastScreenScroll = mOverScrollX;
+ if (!mVertical) {
+ if (mOverScrollX != mLastScreenScroll || mForceScreenScrolled) {
+ screenScrolled(mOverScrollX);
+ mLastScreenScroll = mOverScrollX;
+ mForceScreenScrolled = false;
+ }
+ } else {
+ if (mOverScrollY != mLastScreenScroll || mForceScreenScrolled) {
+ screenScrolled(mOverScrollY);
+ mLastScreenScroll = mOverScrollY;
+ mForceScreenScrolled = false;
+ }
}
// Find out which screens are visible; as an optimization we only call draw on them
final int pageCount = getChildCount();
if (pageCount > 0) {
getVisiblePages(mTempVisiblePagesRange);
- final int leftScreen = mTempVisiblePagesRange[0];
- final int rightScreen = mTempVisiblePagesRange[1];
- if (leftScreen != -1 && rightScreen != -1) {
+ final int leftTopScreen = mTempVisiblePagesRange[0];
+ final int rightBottomScreen = mTempVisiblePagesRange[1];
+ if (leftTopScreen != -1 && rightBottomScreen != -1) {
final long drawingTime = getDrawingTime();
// Clip to the bounds
canvas.save();
@@ -812,7 +948,7 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
for (int i = getChildCount() - 1; i >= 0; i--) {
final View v = getPageAt(i);
if (mForceDrawAllChildrenNextFrame ||
- (leftScreen <= i && i <= rightScreen && shouldDrawChild(v))) {
+ (leftTopScreen <= i && i <= rightBottomScreen && shouldDrawChild(v))) {
drawChild(canvas, v, drawingTime);
}
}
@@ -925,14 +1061,15 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
* Return true if a tap at (x, y) should trigger a flip to the previous page.
*/
protected boolean hitsPreviousPage(float x, float y) {
- return (x < getRelativeChildOffset(mCurrentPage) - mPageSpacing);
+ return ((!mVertical ? x : y) < getRelativeChildOffset(mCurrentPage) - mPageSpacing);
}
/**
* Return true if a tap at (x, y) should trigger a flip to the next page.
*/
protected boolean hitsNextPage(float x, float y) {
- return (x > (getMeasuredWidth() - getRelativeChildOffset(mCurrentPage) + mPageSpacing));
+ return ((!mVertical ? x : y) > ((!mVertical ? getMeasuredWidth() : getMeasuredHeight()) -
+ getRelativeChildOffset(mCurrentPage) + mPageSpacing));
}
@Override
@@ -980,10 +1117,13 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
final float y = ev.getY();
// Remember location of down touch
mDownMotionX = x;
+ mDownMotionY = y;
mLastMotionX = x;
mLastMotionY = y;
mLastMotionXRemainder = 0;
+ mLastMotionYRemainder = 0;
mTotalMotionX = 0;
+ mTotalMotionY = 0;
mActivePointerId = ev.getPointerId(0);
mAllowLongPress = true;
@@ -992,8 +1132,9 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
* otherwise don't. mScroller.isFinished should be false when
* being flinged.
*/
- final int xDist = Math.abs(mScroller.getFinalX() - mScroller.getCurrX());
- final boolean finishedScrolling = (mScroller.isFinished() || xDist < mTouchSlop);
+ final int xyDist = Math.abs(!mVertical ? (mScroller.getFinalX() - mScroller.getCurrX()) :
+ (mScroller.getFinalY() - mScroller.getCurrY()));
+ final boolean finishedScrolling = (mScroller.isFinished() || xyDist < mTouchSlop);
if (finishedScrolling) {
mTouchState = TOUCH_STATE_REST;
mScroller.abortAnimation();
@@ -1060,19 +1201,31 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
final int touchSlop = Math.round(touchSlopScale * mTouchSlop);
boolean xPaged = xDiff > mPagingTouchSlop;
+ boolean yPaged = yDiff > mPagingTouchSlop;
boolean xMoved = xDiff > touchSlop;
boolean yMoved = yDiff > touchSlop;
- if (xMoved || xPaged || yMoved) {
- if (mUsePagingTouchSlop ? xPaged : xMoved) {
- // Scroll if the user moved far enough along the X axis
- mTouchState = TOUCH_STATE_SCROLLING;
- mTotalMotionX += Math.abs(mLastMotionX - x);
- mLastMotionX = x;
- mLastMotionXRemainder = 0;
- mTouchX = getScrollX();
- mSmoothingTime = System.nanoTime() / NANOTIME_DIV;
- pageBeginMoving();
+ if (xMoved || (!mVertical ? xPaged : yPaged) || yMoved) {
+ if (!mVertical) {
+ if (mUsePagingTouchSlop ? xPaged : xMoved) {
+ // Scroll if the user moved far enough along the X axis
+ mTouchState = TOUCH_STATE_SCROLLING;
+ mTotalMotionX += Math.abs(mLastMotionX - x);
+ mLastMotionX = x;
+ mLastMotionXRemainder = 0;
+ mTouchX = mScrollX;
+ pageBeginMoving();
+ }
+ } else {
+ if (mUsePagingTouchSlop ? yPaged : yMoved) {
+ // Scroll if the user moved far enough along the X axis
+ mTouchState = TOUCH_STATE_SCROLLING;
+ mTotalMotionY += Math.abs(mLastMotionY - y);
+ mLastMotionY = y;
+ mLastMotionYRemainder = 0;
+ mTouchY = mScrollY;
+ pageBeginMoving();
+ }
}
// Either way, cancel any pending longpress
cancelCurrentPageLongPress();
@@ -1093,11 +1246,13 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
}
protected float getScrollProgress(int screenScroll, View v, int page) {
- final int halfScreenSize = getMeasuredWidth() / 2;
+ final int halfScreenSize = (!mVertical ? getMeasuredWidth() : getMeasuredHeight()) / 2;
+ int screenCenter = screenScroll + (!mVertical ? getMeasuredWidth() : getMeasuredHeight()) / 2;
- int totalDistance = getScaledMeasuredWidth(v) + mPageSpacing;
- int delta = screenScroll - (getChildOffset(page) -
- getRelativeChildOffset(page));
+ int totalDistance = (!mVertical ? getScaledMeasuredWidth(v) :
+ getScaledMeasuredHeight(v)) + mPageSpacing;
+ int delta = screenCenter - (getChildOffset(page) -
+ getRelativeChildOffset(page) + halfScreenSize);
float scrollProgress = delta / (totalDistance * 1.0f);
scrollProgress = Math.min(scrollProgress, 1.0f);
@@ -1113,7 +1268,7 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
}
protected void acceleratedOverScroll(float amount) {
- int screenSize = getMeasuredWidth();
+ int screenSize = !mVertical ? getMeasuredWidth() : getMeasuredHeight();
// We want to reach the max over scroll effect when the user has
// over scrolled half the size of the screen
@@ -1128,17 +1283,27 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
int overScrollAmount = (int) Math.round(f * screenSize);
if (amount < 0) {
- mOverScrollX = overScrollAmount;
- super.scrollTo(0, getScrollY());
+ if (!mVertical) {
+ mOverScrollX = overScrollAmount;
+ mScrollX = 0;
+ } else {
+ mOverScrollY = overScrollAmount;
+ mScrollY = 0;
+ }
} else {
- mOverScrollX = mMaxScrollX + overScrollAmount;
- super.scrollTo(mMaxScrollX, getScrollY());
+ if (!mVertical) {
+ mOverScrollX = mMaxScrollX + overScrollAmount;
+ mScrollX = mMaxScrollX;
+ } else {
+ mOverScrollY = mMaxScrollY + overScrollAmount;
+ mScrollY = mMaxScrollY;
+ }
}
invalidate();
}
protected void dampedOverScroll(float amount) {
- int screenSize = getMeasuredWidth();
+ int screenSize = !mVertical ? getMeasuredWidth() : getMeasuredHeight();
float f = (amount / screenSize);
@@ -1152,11 +1317,21 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
int overScrollAmount = (int) Math.round(OVERSCROLL_DAMP_FACTOR * f * screenSize);
if (amount < 0) {
- mOverScrollX = overScrollAmount;
- super.scrollTo(0, getScrollY());
+ if (!mVertical) {
+ mOverScrollX = overScrollAmount;
+ mScrollX = 0;
+ } else {
+ mOverScrollY = overScrollAmount;
+ mScrollY = 0;
+ }
} else {
- mOverScrollX = mMaxScrollX + overScrollAmount;
- super.scrollTo(mMaxScrollX, getScrollY());
+ if (!mVertical) {
+ mOverScrollX = mMaxScrollX + overScrollAmount;
+ mScrollX = mMaxScrollX;
+ } else {
+ mOverScrollY = mMaxScrollY + overScrollAmount;
+ mScrollY = mMaxScrollY;
+ }
}
invalidate();
}
@@ -1194,8 +1369,11 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
// Remember where the motion event started
mDownMotionX = mLastMotionX = ev.getX();
+ mDownMotionY = mLastMotionY = ev.getY();
mLastMotionXRemainder = 0;
+ mLastMotionYRemainder = 0;
mTotalMotionX = 0;
+ mTotalMotionY = 0;
mActivePointerId = ev.getPointerId(0);
if (mTouchState == TOUCH_STATE_SCROLLING) {
pageBeginMoving();
@@ -1208,23 +1386,39 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
final int pointerIndex = ev.findPointerIndex(mActivePointerId);
final float x = ev.getX(pointerIndex);
final float deltaX = mLastMotionX + mLastMotionXRemainder - x;
+ final float y = ev.getY(pointerIndex);
+ final float deltaY = mLastMotionY + mLastMotionYRemainder - y;
mTotalMotionX += Math.abs(deltaX);
+ mTotalMotionY += Math.abs(deltaY);
// Only scroll and update mLastMotionX if we have moved some discrete amount. We
// keep the remainder because we are actually testing if we've moved from the last
// scrolled position (which is discrete).
- if (Math.abs(deltaX) >= 1.0f) {
- mTouchX += deltaX;
- mSmoothingTime = System.nanoTime() / NANOTIME_DIV;
- if (!mDeferScrollUpdate) {
- scrollBy((int) deltaX, 0);
- if (DEBUG) Log.d(TAG, "onTouchEvent().Scrolling: " + deltaX);
+ if (Math.abs(!mVertical ? deltaX : deltaY) >= 1.0f) {
+ if (!mVertical) {
+ mTouchX += deltaX;
+ mSmoothingTime = System.nanoTime() / NANOTIME_DIV;
+ if (!mDeferScrollUpdate) {
+ scrollBy((int) deltaX, 0);
+ if (DEBUG) Log.d(TAG, "onTouchEvent().Scrolling: " + deltaX);
+ } else {
+ invalidate();
+ }
+ mLastMotionX = x;
+ mLastMotionXRemainder = deltaX - (int) deltaX;
} else {
- invalidate();
+ mTouchY += deltaY;
+ mSmoothingTime = System.nanoTime() / NANOTIME_DIV;
+ if (!mDeferScrollUpdate) {
+ scrollBy(0, (int) deltaY);
+ if (DEBUG) Log.d(TAG, "onTouchEvent().Scrolling: " + deltaY);
+ } else {
+ invalidate();
+ }
+ mLastMotionY = y;
+ mLastMotionYRemainder = deltaY - (int) deltaY;
}
- mLastMotionX = x;
- mLastMotionXRemainder = deltaX - (int) deltaX;
} else {
awakenScrollBars();
}
@@ -1238,25 +1432,30 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
final int activePointerId = mActivePointerId;
final int pointerIndex = ev.findPointerIndex(activePointerId);
final float x = ev.getX(pointerIndex);
+ final float y = ev.getY(pointerIndex);
final VelocityTracker velocityTracker = mVelocityTracker;
velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);
int velocityX = (int) velocityTracker.getXVelocity(activePointerId);
+ int velocityY = (int) velocityTracker.getYVelocity(activePointerId);
final int deltaX = (int) (x - mDownMotionX);
+ final int deltaY = (int) (y - mDownMotionY);
final int pageWidth = getScaledMeasuredWidth(getPageAt(mCurrentPage));
- boolean isSignificantMove = Math.abs(deltaX) > pageWidth *
+ boolean isSignificantMove = Math.abs(!mVertical ? deltaX : deltaY) > pageWidth *
SIGNIFICANT_MOVE_THRESHOLD;
mTotalMotionX += Math.abs(mLastMotionX + mLastMotionXRemainder - x);
+ mTotalMotionY += Math.abs(mLastMotionY + mLastMotionYRemainder - y);
boolean isFling = mTotalMotionX > MIN_LENGTH_FOR_FLING &&
- Math.abs(velocityX) > mFlingThresholdVelocity;
+ Math.abs(!mVertical ? velocityX : velocityY) > mFlingThresholdVelocity;
// In the case that the page is moved far to one direction and then is flung
// in the opposite direction, we use a threshold to determine whether we should
// just return to the starting page, or if we should skip one further.
boolean returnToOriginalPage = false;
- if (Math.abs(deltaX) > pageWidth * RETURN_TO_ORIGINAL_PAGE_THRESHOLD &&
- Math.signum(velocityX) != Math.signum(deltaX) && isFling) {
+ if (Math.abs(!mVertical ? deltaX : deltaY) > pageWidth * RETURN_TO_ORIGINAL_PAGE_THRESHOLD &&
+ Math.signum(!mVertical ? velocityX : velocityY) !=
+ Math.signum(!mVertical ? deltaX : deltaY) && isFling) {
returnToOriginalPage = true;
}
@@ -1264,17 +1463,32 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
// We give flings precedence over large moves, which is why we short-circuit our
// test for a large move if a fling has been registered. That is, a large
// move to the left and fling to the right will register as a fling to the right.
- if (((isSignificantMove && deltaX > 0 && !isFling) ||
- (isFling && velocityX > 0)) && mCurrentPage > 0) {
- finalPage = returnToOriginalPage ? mCurrentPage : mCurrentPage - 1;
- snapToPageWithVelocity(finalPage, velocityX);
- } else if (((isSignificantMove && deltaX < 0 && !isFling) ||
- (isFling && velocityX < 0)) &&
- mCurrentPage < getChildCount() - 1) {
- finalPage = returnToOriginalPage ? mCurrentPage : mCurrentPage + 1;
- snapToPageWithVelocity(finalPage, velocityX);
+ if (!mVertical) {
+ if (((isSignificantMove && deltaX > 0 && !isFling) ||
+ (isFling && velocityX > 0)) && mCurrentPage > 0) {
+ finalPage = returnToOriginalPage ? mCurrentPage : mCurrentPage - 1;
+ snapToPageWithVelocity(finalPage, velocityX);
+ } else if (((isSignificantMove && deltaX < 0 && !isFling) ||
+ (isFling && velocityX < 0)) &&
+ mCurrentPage < getChildCount() - 1) {
+ finalPage = returnToOriginalPage ? mCurrentPage : mCurrentPage + 1;
+ snapToPageWithVelocity(finalPage, velocityX);
+ } else {
+ snapToDestination();
+ }
} else {
- snapToDestination();
+ if (((isSignificantMove && deltaY > 0 && !isFling) ||
+ (isFling && velocityY > 0)) && mCurrentPage > 0) {
+ finalPage = returnToOriginalPage ? mCurrentPage : mCurrentPage - 1;
+ snapToPageWithVelocity(finalPage, velocityY);
+ } else if (((isSignificantMove && deltaY < 0 && !isFling) ||
+ (isFling && velocityY < 0)) &&
+ mCurrentPage < getChildCount() - 1) {
+ finalPage = returnToOriginalPage ? mCurrentPage : mCurrentPage + 1;
+ snapToPageWithVelocity(finalPage, velocityY);
+ } else {
+ snapToDestination();
+ }
}
} else if (mTouchState == TOUCH_STATE_PREV_PAGE) {
// at this point we have not moved beyond the touch slop
@@ -1374,8 +1588,9 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
// TODO: Make this decision more intelligent.
final int newPointerIndex = pointerIndex == 0 ? 1 : 0;
mLastMotionX = mDownMotionX = ev.getX(newPointerIndex);
- mLastMotionY = ev.getY(newPointerIndex);
+ mLastMotionY = mDownMotionY = ev.getY(newPointerIndex);
mLastMotionXRemainder = 0;
+ mLastMotionYRemainder = 0;
mActivePointerId = ev.getPointerId(newPointerIndex);
if (mVelocityTracker != null) {
mVelocityTracker.clear();
@@ -1396,12 +1611,13 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
protected int getChildIndexForRelativeOffset(int relativeOffset) {
final int childCount = getChildCount();
- int left;
- int right;
+ int leftTop;
+ int rightBottom;
for (int i = 0; i < childCount; ++i) {
- left = getRelativeChildOffset(i);
- right = (left + getScaledMeasuredWidth(getPageAt(i)));
- if (left <= relativeOffset && relativeOffset <= right) {
+ leftTop = getRelativeChildOffset(i);
+ rightBottom = (leftTop + (!mVertical ? getScaledMeasuredWidth(getPageAt(i)) :
+ getScaledMeasuredHeight(getPageAt(i))));
+ if (leftTop <= relativeOffset && relativeOffset <= rightBottom) {
return i;
}
}
@@ -1416,16 +1632,31 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
return (minWidth > measuredWidth) ? minWidth : measuredWidth;
}
+ protected int getChildHeight(int index) {
+ // This functions are called enough times that it actually makes a difference in the
+ // profiler -- so just inline the max() here
+ final int measuredHeight = getPageAt(index).getMeasuredHeight();
+ final int minHeight = mMinimumHeight;
+ return (minHeight > measuredHeight) ? minHeight : measuredHeight;
+ }
+
int getPageNearestToCenterOfScreen() {
int minDistanceFromScreenCenter = Integer.MAX_VALUE;
int minDistanceFromScreenCenterIndex = -1;
- int screenCenter = getScrollX() + (getMeasuredWidth() / 2);
+ int screenCenter = !mVertical ? mScrollX + (getMeasuredWidth() / 2) :
+ mScrollY + (getMeasuredHeight() / 2);
final int childCount = getChildCount();
for (int i = 0; i < childCount; ++i) {
- View layout = (View) getPageAt(i);
- int childWidth = getScaledMeasuredWidth(layout);
- int halfChildWidth = (childWidth / 2);
- int childCenter = getChildOffset(i) + halfChildWidth;
+ View layout = getPageAt(i);
+ int halfChild;
+ if (!mVertical) {
+ int childWidth = getScaledMeasuredWidth(layout);
+ halfChild = (childWidth / 2);
+ } else {
+ int childHeight = getScaledMeasuredHeight(layout);
+ halfChild = (childHeight / 2);
+ }
+ int childCenter = getChildOffset(i) + halfChild;
int distanceFromScreenCenter = Math.abs(childCenter - screenCenter);
if (distanceFromScreenCenter < minDistanceFromScreenCenter) {
minDistanceFromScreenCenter = distanceFromScreenCenter;
@@ -1475,13 +1706,13 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
protected void snapToPageWithVelocity(int whichPage, int velocity) {
whichPage = Math.max(0, Math.min(whichPage, getChildCount() - 1));
- int halfScreenSize = getMeasuredWidth() / 2;
+ int halfScreenSize = (!mVertical ? getMeasuredWidth() : getMeasuredHeight()) / 2;
if (DEBUG) Log.d(TAG, "snapToPage.getChildOffset(): " + getChildOffset(whichPage));
if (DEBUG) Log.d(TAG, "snapToPageWithVelocity.getRelativeChildOffset(): "
+ getMeasuredWidth() + ", " + getChildWidth(whichPage));
- final int newX = getChildOffset(whichPage) - getRelativeChildOffset(whichPage);
- int delta = newX - mUnboundedScrollX;
+ final int newXY = getChildOffset(whichPage) - getRelativeChildOffset(whichPage);
+ int delta = newXY - (!mVertical ? mUnboundedScrollX : mUnboundedScrollY);
int duration = 0;
if (Math.abs(velocity) < mMinFlingVelocity) {
@@ -1521,9 +1752,9 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
if (DEBUG) Log.d(TAG, "snapToPage.getChildOffset(): " + getChildOffset(whichPage));
if (DEBUG) Log.d(TAG, "snapToPage.getRelativeChildOffset(): " + getMeasuredWidth() + ", "
+ getChildWidth(whichPage));
- int newX = getChildOffset(whichPage) - getRelativeChildOffset(whichPage);
- final int sX = mUnboundedScrollX;
- final int delta = newX - sX;
+ int newXY = getChildOffset(whichPage) - getRelativeChildOffset(whichPage);
+ final int sXY = !mVertical ? mUnboundedScrollX : mUnboundedScrollY;
+ final int delta = newXY - sXY;
snapToPage(whichPage, delta, duration);
}
@@ -1543,7 +1774,11 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
}
if (!mScroller.isFinished()) mScroller.abortAnimation();
- mScroller.startScroll(mUnboundedScrollX, 0, delta, 0, duration);
+ if (!mVertical) {
+ mScroller.startScroll(mUnboundedScrollX, 0, delta, 0, duration);
+ } else {
+ mScroller.startScroll(0, mUnboundedScrollY, 0, delta, duration);
+ }
// Load associated pages immediately if someone else is handling the scroll, otherwise defer
// loading associated pages until the scroll settles
@@ -1875,14 +2110,14 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
if (!isScrollingIndicatorEnabled()) return;
if (mScrollIndicator == null) return;
int numPages = getChildCount();
- int pageWidth = getMeasuredWidth();
+ int pageSize = !mVertical ? getMeasuredWidth() : getMeasuredHeight();
int lastChildIndex = Math.max(0, getChildCount() - 1);
- int maxScrollX = getChildOffset(lastChildIndex) - getRelativeChildOffset(lastChildIndex);
- int trackWidth = pageWidth - mScrollIndicatorPaddingLeft - mScrollIndicatorPaddingRight;
+ int maxScroll = getChildOffset(lastChildIndex) - getRelativeChildOffset(lastChildIndex);
+ int trackWidth = pageSize - mScrollIndicatorPaddingLeft - mScrollIndicatorPaddingRight;
int indicatorWidth = mScrollIndicator.getMeasuredWidth() -
mScrollIndicator.getPaddingLeft() - mScrollIndicator.getPaddingRight();
- float offset = Math.max(0f, Math.min(1f, (float) getScrollX() / maxScrollX));
+ float offset = Math.max(0f, Math.min(1f, (float) (!mVertical ? getScrollX() : getScrollY()) / maxScroll));
int indicatorSpace = trackWidth / numPages;
int indicatorPos = (int) (offset * (trackWidth - indicatorSpace)) + mScrollIndicatorPaddingLeft;
if (hasElasticScrollIndicator()) {