Ensuring that fast scrolling to predictions scrolls list to the top
- Fixes a long standing issue with fast-scrolling to the predicted apps not quite scrolling the list to the top of the screen. - Fixes an issue where we don’t scroll exactly to the fast scroll position due to rounding - Also fixes a small issue where the thumb would not update when the fast scroll popup was no longer showing, even while dragging. Bug: 30023608 Change-Id: I6b5080c6aea521ff03dca24317f0405c02725061
This commit is contained in:
@@ -246,13 +246,18 @@ public abstract class BaseRecyclerView extends RecyclerView
|
||||
(int) (((float) scrollY / availableScrollHeight) * availableScrollBarHeight);
|
||||
|
||||
// Calculate the position and size of the scroll bar
|
||||
int scrollBarX;
|
||||
mScrollbar.setThumbOffset(getScrollBarX(), scrollBarY);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the x position for the scrollbar thumb
|
||||
*/
|
||||
protected int getScrollBarX() {
|
||||
if (Utilities.isRtl(getResources())) {
|
||||
scrollBarX = mBackgroundPadding.left;
|
||||
return mBackgroundPadding.left;
|
||||
} else {
|
||||
scrollBarX = getWidth() - mBackgroundPadding.right - mScrollbar.getThumbWidth();
|
||||
return getWidth() - mBackgroundPadding.right - mScrollbar.getThumbWidth();
|
||||
}
|
||||
mScrollbar.setThumbOffset(scrollBarX, scrollBarY);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -156,10 +156,6 @@ public class BaseRecyclerViewFastScrollBar {
|
||||
return mThumbMaxWidth;
|
||||
}
|
||||
|
||||
public float getLastTouchY() {
|
||||
return mLastTouchY;
|
||||
}
|
||||
|
||||
public boolean isDraggingThumb() {
|
||||
return mIsDragging;
|
||||
}
|
||||
@@ -210,6 +206,7 @@ public class BaseRecyclerViewFastScrollBar {
|
||||
mPopup.animateVisibility(!sectionName.isEmpty());
|
||||
mRv.invalidate(mPopup.updateFastScrollerBounds(lastY));
|
||||
mLastTouchY = boundedY;
|
||||
setThumbOffset(mRv.getScrollBarX(), (int) mLastTouchY);
|
||||
}
|
||||
break;
|
||||
case MotionEvent.ACTION_UP:
|
||||
|
||||
@@ -23,6 +23,7 @@ import com.android.launcher3.FastBitmapDrawable;
|
||||
import com.android.launcher3.util.Thunk;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
|
||||
public class AllAppsFastScrollHelper implements AllAppsGridAdapter.BindViewCallback {
|
||||
|
||||
@@ -142,13 +143,22 @@ public class AllAppsFastScrollHelper implements AllAppsGridAdapter.BindViewCallb
|
||||
}
|
||||
|
||||
// Calculate the full animation from the current scroll position to the final scroll
|
||||
// position, and then run the animation for the duration.
|
||||
// position, and then run the animation for the duration. If we are scrolling to the
|
||||
// first fast scroll section, then just scroll to the top of the list itself.
|
||||
List<AlphabeticalAppsList.FastScrollSectionInfo> fastScrollSections =
|
||||
mApps.getFastScrollerSections();
|
||||
int newPosition = info.fastScrollToItem.position;
|
||||
int newScrollY = Math.min(availableScrollHeight, mRv.getCurrentScrollY(newPosition, 0));
|
||||
int newScrollY = fastScrollSections.size() > 0 && fastScrollSections.get(0) == info
|
||||
? 0
|
||||
: Math.min(availableScrollHeight, mRv.getCurrentScrollY(newPosition, 0));
|
||||
int numFrames = mFastScrollFrames.length;
|
||||
int deltaY = newScrollY - scrollY;
|
||||
float ySign = Math.signum(deltaY);
|
||||
int step = (int) (ySign * Math.ceil((float) Math.abs(deltaY) / numFrames));
|
||||
for (int i = 0; i < numFrames; i++) {
|
||||
// TODO(winsonc): We can interpolate this as well.
|
||||
mFastScrollFrames[i] = (newScrollY - scrollY) / numFrames;
|
||||
mFastScrollFrames[i] = (int) (ySign * Math.min(Math.abs(step), Math.abs(deltaY)));
|
||||
deltaY -= step;
|
||||
}
|
||||
mFastScrollFrameIndex = 0;
|
||||
mRv.postOnAnimation(mSmoothSnapNextFrameRunnable);
|
||||
|
||||
@@ -377,10 +377,6 @@ public class AllAppsGridAdapter extends RecyclerView.Adapter<AllAppsGridAdapter.
|
||||
return isViewType(viewType, VIEW_TYPE_MASK_ICON);
|
||||
}
|
||||
|
||||
public static boolean isPredictionIconViewType(int viewType) {
|
||||
return isViewType(viewType, VIEW_TYPE_PREDICTION_ICON);
|
||||
}
|
||||
|
||||
public static boolean isViewType(int viewType, int viewTypeMask) {
|
||||
return (viewType & viewTypeMask) != 0;
|
||||
}
|
||||
|
||||
@@ -325,25 +325,15 @@ public class AllAppsRecyclerView extends BaseRecyclerView
|
||||
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 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()) {
|
||||
// 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 scrollBarX = getScrollBarX();
|
||||
int scrollBarY = mBackgroundPadding.top +
|
||||
(int) (((float) scrollY / availableScrollHeight) * availableScrollBarHeight);
|
||||
|
||||
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) {
|
||||
|
||||
Reference in New Issue
Block a user