diff options
Diffstat (limited to 'src/com/android/launcher3/PagedView.java')
-rw-r--r-- | src/com/android/launcher3/PagedView.java | 130 |
1 files changed, 79 insertions, 51 deletions
diff --git a/src/com/android/launcher3/PagedView.java b/src/com/android/launcher3/PagedView.java index 8d5d8dd4d..48fc0c98f 100644 --- a/src/com/android/launcher3/PagedView.java +++ b/src/com/android/launcher3/PagedView.java @@ -74,11 +74,12 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc private static final int MIN_LENGTH_FOR_FLING = 25; protected static final int PAGE_SNAP_ANIMATION_DURATION = 750; + protected static final int OVER_SCROLL_PAGE_SNAP_ANIMATION_DURATION = 350; protected static final int SLOW_PAGE_SNAP_ANIMATION_DURATION = 950; protected static final float NANOTIME_DIV = 1000000000.0f; private static final float OVERSCROLL_ACCELERATE_FACTOR = 2; - private static final float OVERSCROLL_DAMP_FACTOR = 0.14f; + private static final float OVERSCROLL_DAMP_FACTOR = 0.07f; private static final float RETURN_TO_ORIGINAL_PAGE_THRESHOLD = 0.33f; // The page is moved more than halfway, automatically move to the next page on touch up. @@ -152,16 +153,11 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc protected int mTouchState = TOUCH_STATE_REST; protected boolean mForceScreenScrolled = false; - protected OnLongClickListener mLongClickListener; protected int mTouchSlop; private int mPagingTouchSlop; private int mMaximumVelocity; - protected int mPageLayoutPaddingTop; - protected int mPageLayoutPaddingBottom; - protected int mPageLayoutPaddingLeft; - protected int mPageLayoutPaddingRight; protected int mPageLayoutWidthGap; protected int mPageLayoutHeightGap; protected int mCellCountX = 0; @@ -171,6 +167,7 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc protected int mUnboundedScrollX; protected int[] mTempVisiblePagesRange = new int[2]; protected boolean mForceDrawAllChildrenNextFrame; + private boolean mSpacePagesAutomatically = false; // mOverScrollX is equal to getScrollX() when we're within the normal scroll range. Otherwise // it is equal to the scaled overscroll position. We use a separate value so as to prevent @@ -283,14 +280,6 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.PagedView, defStyle, 0); - mPageLayoutPaddingTop = a.getDimensionPixelSize( - R.styleable.PagedView_pageLayoutPaddingTop, 0); - mPageLayoutPaddingBottom = a.getDimensionPixelSize( - R.styleable.PagedView_pageLayoutPaddingBottom, 0); - mPageLayoutPaddingLeft = a.getDimensionPixelSize( - R.styleable.PagedView_pageLayoutPaddingLeft, 0); - mPageLayoutPaddingRight = a.getDimensionPixelSize( - R.styleable.PagedView_pageLayoutPaddingRight, 0); mPageLayoutWidthGap = a.getDimensionPixelSize( R.styleable.PagedView_pageLayoutWidthGap, 0); mPageLayoutHeightGap = a.getDimensionPixelSize( @@ -339,8 +328,9 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc // Hook up the page indicator ViewGroup parent = (ViewGroup) getParent(); + ViewGroup grandParent = (ViewGroup) parent.getParent(); if (mPageIndicator == null && mPageIndicatorViewId > -1) { - mPageIndicator = (PageIndicator) parent.findViewById(mPageIndicatorViewId); + mPageIndicator = (PageIndicator) grandParent.findViewById(mPageIndicatorViewId); mPageIndicator.removeAllMarkers(mAllowPagedViewAnimations); ArrayList<PageIndicator.PageMarkerResources> markers = @@ -547,6 +537,19 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc mNextPage = INVALID_PAGE; } + private int validateNewPage(int newPage) { + int validatedPage = newPage; + // When in free scroll mode, we need to clamp to the free scroll page range. + if (mFreeScroll) { + getFreeScrollPageRange(mTempVisiblePagesRange); + validatedPage = Math.max(mTempVisiblePagesRange[0], + Math.min(newPage, mTempVisiblePagesRange[1])); + } + // Ensure that it is clamped by the actual set of children in all cases + validatedPage = Math.max(0, Math.min(validatedPage, getPageCount() - 1)); + return validatedPage; + } + /** * Sets the current page. */ @@ -560,7 +563,7 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc return; } mForceScreenScrolled = true; - mCurrentPage = Math.max(0, Math.min(currentPage, getPageCount() - 1)); + mCurrentPage = validateNewPage(currentPage); updateCurrentPageScroll(); notifyPageSwitchListener(); invalidate(); @@ -591,8 +594,11 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc private void updatePageIndicator() { // Update the page indicator (when we aren't reordering) - if (mPageIndicator != null && !isReordering(false)) { - mPageIndicator.setActiveMarker(getNextPage()); + if (mPageIndicator != null) { + mPageIndicator.setContentDescription(getPageIndicatorDescription()); + if (!isReordering(false)) { + mPageIndicator.setActiveMarker(getNextPage()); + } } } protected void pageBeginMoving() { @@ -727,7 +733,7 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc } else if (mNextPage != INVALID_PAGE) { sendScrollAccessibilityEvent(); - mCurrentPage = Math.max(0, Math.min(mNextPage, getPageCount() - 1)); + mCurrentPage = validateNewPage(mNextPage); mNextPage = INVALID_PAGE; notifyPageSwitchListener(); @@ -843,6 +849,7 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc final int verticalPadding = getPaddingTop() + getPaddingBottom(); final int horizontalPadding = getPaddingLeft() + getPaddingRight(); + int referenceChildWidth = 0; // The children are given the same width and height as the workspace // unless they were set to WRAP_CONTENT if (DEBUG) Log.d(TAG, "PagedView.onMeasure(): " + widthSize + ", " + heightSize); @@ -887,6 +894,9 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc childWidth = getViewportWidth() - mInsets.left - mInsets.right; childHeight = getViewportHeight(); } + if (referenceChildWidth == 0) { + referenceChildWidth = childWidth; + } final int childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(childWidth, childWidthMode); @@ -895,9 +905,24 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc child.measure(childWidthMeasureSpec, childHeightMeasureSpec); } } + if (mSpacePagesAutomatically) { + int spacing = (getViewportWidth() - mInsets.left - mInsets.right + - referenceChildWidth) / 2; + if (spacing >= 0) { + setPageSpacing(spacing); + } + mSpacePagesAutomatically = false; + } setMeasuredDimension(scaledWidthSize, scaledHeightSize); } + /** + * This method should be called once before first layout / measure pass. + */ + protected void setSinglePageInViewport() { + mSpacePagesAutomatically = true; + } + @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { if (!mIsDataReady || getChildCount() == 0) { @@ -974,9 +999,7 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc } if (mFirstLayout && mCurrentPage >= 0 && mCurrentPage < getChildCount()) { - setHorizontalScrollBarEnabled(false); updateCurrentPageScroll(); - setHorizontalScrollBarEnabled(true); mFirstLayout = false; } @@ -1105,7 +1128,7 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc return offset; } - protected void getOverviewModePages(int[] range) { + protected void getFreeScrollPageRange(int[] range) { range[0] = 0; range[1] = Math.max(0, getChildCount() - 1); } @@ -1158,7 +1181,7 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc } protected boolean shouldDrawChild(View child) { - return child.getAlpha() > 0 && child.getVisibility() == VISIBLE; + return child.getVisibility() == VISIBLE; } @Override @@ -1580,29 +1603,20 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc return f * f * f + 1.0f; } - protected void acceleratedOverScroll(float amount) { + protected float acceleratedOverFactor(float amount) { int screenSize = getViewportWidth(); // We want to reach the max over scroll effect when the user has // over scrolled half the size of the screen float f = OVERSCROLL_ACCELERATE_FACTOR * (amount / screenSize); - if (f == 0) return; + if (f == 0) return 0; // Clamp this factor, f, to -1 < f < 1 if (Math.abs(f) >= 1) { f /= Math.abs(f); } - - int overScrollAmount = (int) Math.round(f * screenSize); - if (amount < 0) { - mOverScrollX = overScrollAmount; - super.scrollTo(0, getScrollY()); - } else { - mOverScrollX = mMaxScrollX + overScrollAmount; - super.scrollTo(mMaxScrollX, getScrollY()); - } - invalidate(); + return f; } protected void dampedOverScroll(float amount) { @@ -1621,10 +1635,10 @@ 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()); + super.scrollTo(mOverScrollX, getScrollY()); } else { mOverScrollX = mMaxScrollX + overScrollAmount; - super.scrollTo(mMaxScrollX, getScrollY()); + super.scrollTo(mOverScrollX, getScrollY()); } invalidate(); } @@ -1650,7 +1664,7 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc } void updateFreescrollBounds() { - getOverviewModePages(mTempVisiblePagesRange); + getFreeScrollPageRange(mTempVisiblePagesRange); if (isLayoutRtl()) { mFreeScrollMinScrollX = getScrollForPage(mTempVisiblePagesRange[1]); mFreeScrollMaxScrollX = getScrollForPage(mTempVisiblePagesRange[0]); @@ -1665,7 +1679,7 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc if (mFreeScroll) { updateFreescrollBounds(); - getOverviewModePages(mTempVisiblePagesRange); + getFreeScrollPageRange(mTempVisiblePagesRange); if (getCurrentPage() < mTempVisiblePagesRange[0]) { setCurrentPage(mTempVisiblePagesRange[0]); } else if (getCurrentPage() > mTempVisiblePagesRange[1]) { @@ -1684,7 +1698,7 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc if (mDragView != null) { int dragX = (int) (mDragView.getLeft() + (mDragView.getMeasuredWidth() / 2) + mDragView.getTranslationX()); - getOverviewModePages(mTempVisiblePagesRange); + getFreeScrollPageRange(mTempVisiblePagesRange); int minDistance = Integer.MAX_VALUE; int minIndex = indexOfChild(mDragView); for (int i = mTempVisiblePagesRange[0]; i <= mTempVisiblePagesRange[1]; i++) { @@ -1801,7 +1815,7 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc !isHoveringOverDelete) { mTempVisiblePagesRange[0] = 0; mTempVisiblePagesRange[1] = getPageCount() - 1; - getOverviewModePages(mTempVisiblePagesRange); + getFreeScrollPageRange(mTempVisiblePagesRange); if (mTempVisiblePagesRange[0] <= pageUnderPointIndex && pageUnderPointIndex <= mTempVisiblePagesRange[1] && pageUnderPointIndex != mSidePageHoverIndex && mScroller.isFinished()) { @@ -2124,8 +2138,20 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc return minDistanceFromScreenCenterIndex; } + protected boolean isInOverScroll() { + return (mOverScrollX > mMaxScrollX || mOverScrollX < 0); + } + + protected int getPageSnapDuration() { + if (isInOverScroll()) { + return OVER_SCROLL_PAGE_SNAP_ANIMATION_DURATION; + } + return PAGE_SNAP_ANIMATION_DURATION; + + } + protected void snapToDestination() { - snapToPage(getPageNearestToCenterOfScreen(), PAGE_SNAP_ANIMATION_DURATION); + snapToPage(getPageNearestToCenterOfScreen(), getPageSnapDuration()); } private static class ScrollInterpolator implements Interpolator { @@ -2149,17 +2175,17 @@ 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)); + whichPage = validateNewPage(whichPage); int halfScreenSize = getViewportWidth() / 2; final int newX = getScrollForPage(whichPage); int delta = newX - mUnboundedScrollX; int duration = 0; - if (Math.abs(velocity) < mMinFlingVelocity) { + if (Math.abs(velocity) < mMinFlingVelocity || isInOverScroll()) { // If the velocity is low enough, then treat this more as an automatic page advance // as opposed to an apparent physical response to flinging - snapToPage(whichPage, PAGE_SNAP_ANIMATION_DURATION); + snapToPage(whichPage, getPageSnapDuration()); return; } @@ -2183,11 +2209,11 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc } protected void snapToPage(int whichPage) { - snapToPage(whichPage, PAGE_SNAP_ANIMATION_DURATION); + snapToPage(whichPage, getPageSnapDuration()); } protected void snapToPageImmediately(int whichPage) { - snapToPage(whichPage, PAGE_SNAP_ANIMATION_DURATION, true, null); + snapToPage(whichPage, getPageSnapDuration(), true, null); } protected void snapToPage(int whichPage, int duration) { @@ -2200,7 +2226,7 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc protected void snapToPage(int whichPage, int duration, boolean immediate, TimeInterpolator interpolator) { - whichPage = Math.max(0, Math.min(whichPage, getPageCount() - 1)); + whichPage = validateNewPage(whichPage); int newX = getScrollForPage(whichPage); final int sX = mUnboundedScrollX; @@ -2214,6 +2240,8 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc protected void snapToPage(int whichPage, int delta, int duration, boolean immediate, TimeInterpolator interpolator) { + whichPage = validateNewPage(whichPage); + mNextPage = whichPage; View focusedChild = getFocusedChild(); if (focusedChild != null && whichPage != mCurrentPage && @@ -2482,11 +2510,11 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc public boolean startReordering(View v) { int dragViewIndex = indexOfChild(v); - if (mTouchState != TOUCH_STATE_REST) return false; + if (mTouchState != TOUCH_STATE_REST || dragViewIndex == -1) return false; mTempVisiblePagesRange[0] = 0; mTempVisiblePagesRange[1] = getPageCount() - 1; - getOverviewModePages(mTempVisiblePagesRange); + getFreeScrollPageRange(mTempVisiblePagesRange); mReorderingStarted = true; // Check if we are within the reordering range @@ -2619,7 +2647,7 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc // in the layout) // NOTE: We can make an assumption here because we have side-bound pages that we // will always have pages to animate in from the left - getOverviewModePages(mTempVisiblePagesRange); + getFreeScrollPageRange(mTempVisiblePagesRange); boolean isLastWidgetPage = (mTempVisiblePagesRange[0] == mTempVisiblePagesRange[1]); boolean slideFromLeft = (isLastWidgetPage || dragViewIndex > mTempVisiblePagesRange[0]); |