private void completeScroll() { boolean needPopulate = mScrolling; if (needPopulate) { // Done with scroll, no longer want to cache view drawing. setDrawingCacheEnabled(false); mScroller.abortAnimation(); int oldX = getScrollX(); int oldY = getScrollY(); int x = mScroller.getCurrX(); int y = mScroller.getCurrY(); if (oldX != x || oldY != y) { scrollTo(x, y); } if (mIsOpen) { if (mOnInteractListener != null) { mOnInteractListener.onOpened(); } } else { if (mOnInteractListener != null) { mOnInteractListener.onClosed(); } } } mScrolling = false; }
/** * Like {@link View#scrollBy}, but scroll smoothly instead of immediately. * * @param x the number of pixels to scroll by on the X axis * @param y the number of pixels to scroll by on the Y axis * @param velocity the velocity associated with a fling, if applicable. (0 otherwise) */ void smoothScrollTo(int x, int y, int velocity) { if (getChildCount() == 0) { setDrawingCacheEnabled(false); return; } int sx = getScrollX(); int sy = getScrollY(); int dx = x - sx; int dy = y - sy; if (dx == 0 && dy == 0) { completeScroll(); if (mIsOpen) { if (mOnInteractListener != null) { mOnInteractListener.onOpened(); } } else { if (mOnInteractListener != null) { mOnInteractListener.onClosed(); } } return; } setDrawingCacheEnabled(true); mScrolling = true; final int width = getWidth(); final int halfWidth = width / 2; final float distanceRatio = Math.min(1f, 1.0f * Math.abs(dx) / width); final float distance = halfWidth + halfWidth * distanceInfluenceForSnapDuration(distanceRatio); int duration = 0; velocity = Math.abs(velocity); if (velocity > 0) { duration = 4 * Math.round(1000 * Math.abs(distance / velocity)); } else { duration = MAX_SCROLLING_DURATION; } duration = Math.min(duration, MAX_SCROLLING_DURATION); mScroller.startScroll(sx, sy, dx, dy, duration); invalidate(); }