diff options
Diffstat (limited to 'src/com/android/launcher3/allapps/AllAppsRecyclerView.java')
-rw-r--r-- | src/com/android/launcher3/allapps/AllAppsRecyclerView.java | 68 |
1 files changed, 59 insertions, 9 deletions
diff --git a/src/com/android/launcher3/allapps/AllAppsRecyclerView.java b/src/com/android/launcher3/allapps/AllAppsRecyclerView.java index 5aa973a15..5ec8bb258 100644 --- a/src/com/android/launcher3/allapps/AllAppsRecyclerView.java +++ b/src/com/android/launcher3/allapps/AllAppsRecyclerView.java @@ -72,6 +72,7 @@ public class AllAppsRecyclerView extends BaseRecyclerView public AllAppsRecyclerView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr); + mScrollbar.setDetachThumbOnFastScroll(); } /** @@ -168,8 +169,8 @@ public class AllAppsRecyclerView extends BaseRecyclerView } // Map the touch position back to the scroll of the recycler view - getCurScrollState(mScrollPosState, mApps.getAdapterItems()); - int availableScrollHeight = getAvailableScrollHeight(rowCount, mScrollPosState.rowHeight, 0); + getCurScrollState(mScrollPosState); + int availableScrollHeight = getAvailableScrollHeight(rowCount, mScrollPosState.rowHeight); LinearLayoutManager layoutManager = (LinearLayoutManager) getLayoutManager(); if (mFastScrollMode == FAST_SCROLL_MODE_FREE_SCROLL) { layoutManager.scrollToPositionWithOffset(0, (int) -(availableScrollHeight * touchFraction)); @@ -216,24 +217,73 @@ public class AllAppsRecyclerView extends BaseRecyclerView * Updates the bounds for the scrollbar. */ @Override - public void onUpdateScrollbar() { + public void onUpdateScrollbar(int dy) { List<AlphabeticalAppsList.AdapterItem> items = mApps.getAdapterItems(); // Skip early if there are no items or we haven't been measured if (items.isEmpty() || mNumAppsPerRow == 0) { - mScrollbar.setScrollbarThumbOffset(-1, -1); + mScrollbar.setThumbOffset(-1, -1); return; } // Find the index and height of the first visible row (all rows have the same height) int rowCount = mApps.getNumAppRows(); - getCurScrollState(mScrollPosState, items); + getCurScrollState(mScrollPosState); if (mScrollPosState.rowIndex < 0) { - mScrollbar.setScrollbarThumbOffset(-1, -1); + mScrollbar.setThumbOffset(-1, -1); return; } - synchronizeScrollBarThumbOffsetToViewScroll(mScrollPosState, rowCount, 0); + // Only show the scrollbar if there is height to be scrolled + int availableScrollBarHeight = getAvailableScrollBarHeight(); + int availableScrollHeight = getAvailableScrollHeight(mApps.getNumAppRows(), mScrollPosState.rowHeight); + if (availableScrollHeight <= 0) { + mScrollbar.setThumbOffset(-1, -1); + return; + } + + // Calculate the current scroll position, the scrollY of the recycler view accounts for the + // view padding, while the scrollBarY is drawn right up to the background padding (ignoring + // padding) + int scrollY = getPaddingTop() + + (mScrollPosState.rowIndex * mScrollPosState.rowHeight) - mScrollPosState.rowTopOffset; + int scrollBarY = mBackgroundPadding.top + + (int) (((float) scrollY / availableScrollHeight) * availableScrollBarHeight); + + if (mScrollbar.isThumbDetached()) { + int scrollBarX; + if (Utilities.isRtl(getResources())) { + scrollBarX = mBackgroundPadding.left; + } else { + scrollBarX = getWidth() - mBackgroundPadding.right - mScrollbar.getThumbWidth(); + } + + if (mScrollbar.isDraggingThumb()) { + // If the thumb is detached, then just update the thumb to the current + // touch position + mScrollbar.setThumbOffset(scrollBarX, (int) mScrollbar.getLastTouchY()); + } else { + int thumbScrollY = mScrollbar.getThumbOffset().y; + int diffScrollY = scrollBarY - thumbScrollY; + if (diffScrollY * dy > 0f) { + // User is scrolling in the same direction the thumb needs to catch up to the + // current scroll position. + thumbScrollY += dy < 0 ? Math.max(dy, diffScrollY) : Math.min(dy, diffScrollY); + thumbScrollY = Math.max(0, Math.min(availableScrollBarHeight, thumbScrollY)); + mScrollbar.setThumbOffset(scrollBarX, thumbScrollY); + if (scrollBarY == thumbScrollY) { + mScrollbar.reattachThumbToScroll(); + } + } else { + // User is scrolling in an opposite direction to the direction that the thumb + // needs to catch up to the scroll position. Do nothing except for updating + // the scroll bar x to match the thumb width. + mScrollbar.setThumbOffset(scrollBarX, thumbScrollY); + } + } + } else { + synchronizeScrollBarThumbOffsetToViewScroll(mScrollPosState, rowCount); + } } /** @@ -285,13 +335,13 @@ public class AllAppsRecyclerView extends BaseRecyclerView /** * Returns the current scroll state of the apps rows. */ - private void getCurScrollState(ScrollPositionState stateOut, - List<AlphabeticalAppsList.AdapterItem> items) { + protected void getCurScrollState(ScrollPositionState stateOut) { stateOut.rowIndex = -1; stateOut.rowTopOffset = -1; stateOut.rowHeight = -1; // Return early if there are no items or we haven't been measured + List<AlphabeticalAppsList.AdapterItem> items = mApps.getAdapterItems(); if (items.isEmpty() || mNumAppsPerRow == 0) { return; } |