diff --git a/src/com/android/launcher3/BaseRecyclerViewFastScrollBar.java b/src/com/android/launcher3/BaseRecyclerViewFastScrollBar.java index a6801696a6..fd0045e630 100644 --- a/src/com/android/launcher3/BaseRecyclerViewFastScrollBar.java +++ b/src/com/android/launcher3/BaseRecyclerViewFastScrollBar.java @@ -27,7 +27,6 @@ import android.graphics.Path; import android.graphics.Point; import android.graphics.Rect; import android.view.MotionEvent; -import android.view.VelocityTracker; import android.view.ViewConfiguration; import com.android.launcher3.util.Thunk; @@ -293,7 +292,7 @@ public class BaseRecyclerViewFastScrollBar { /** * Returns whether the specified points are near the scroll bar bounds. */ - private boolean isNearThumb(int x, int y) { + public boolean isNearThumb(int x, int y) { mTmpRect.set(mThumbOffset.x, mThumbOffset.y, mThumbOffset.x + mThumbWidth, mThumbOffset.y + mThumbHeight); mTmpRect.inset(mTouchInset, mTouchInset); diff --git a/src/com/android/launcher3/allapps/AllAppsContainerView.java b/src/com/android/launcher3/allapps/AllAppsContainerView.java index 2c9f810cf0..a74c4c5ab1 100644 --- a/src/com/android/launcher3/allapps/AllAppsContainerView.java +++ b/src/com/android/launcher3/allapps/AllAppsContainerView.java @@ -257,9 +257,24 @@ public class AllAppsContainerView extends BaseContainerView implements DragSourc mAppsRecyclerView.scrollToTop(); } - public boolean isScrollAtTop() { - return ((LinearLayoutManager) mAppsRecyclerView.getLayoutManager()) - .findFirstVisibleItemPosition() == 1; + /** + * Returns whether the view itself will handle the touch event or not. + */ + public boolean shouldContainerScroll(float x, float y) { + int[] point = new int[2]; + point[0] = (int) x; + point[1] = (int) y; + Utilities.mapCoordInSelfToDescendent(mAppsRecyclerView, this, point); + + // if the MotionEvent is inside the thumb, container should not be pulled down. + if (mAppsRecyclerView.getScrollBar().isNearThumb(point[0], point[1])){ + return false; + } + // If scroller is at the very top, then it's okay for the container to be pulled down. + if (Float.compare(0f, mAppsRecyclerView.getScrollBar().getThumbOffset().y) == 0) { + return true; + } + return false; } /** * Focuses the search field and begins an app search. diff --git a/src/com/android/launcher3/allapps/AllAppsTransitionController.java b/src/com/android/launcher3/allapps/AllAppsTransitionController.java index 829a566b92..d70ee477a1 100644 --- a/src/com/android/launcher3/allapps/AllAppsTransitionController.java +++ b/src/com/android/launcher3/allapps/AllAppsTransitionController.java @@ -9,9 +9,7 @@ import android.util.Log; import android.view.MotionEvent; import android.view.View; import android.view.animation.AccelerateInterpolator; -import android.view.animation.DecelerateInterpolator; import android.view.animation.Interpolator; -import android.view.animation.LinearInterpolator; import com.android.launcher3.CellLayout; import com.android.launcher3.Hotseat; @@ -39,7 +37,7 @@ public class AllAppsTransitionController implements TouchController, VerticalPul private final Interpolator mAccelInterpolator = new AccelerateInterpolator(1f); private static final float ANIMATION_DURATION = 2000; - private static final float FINAL_ALPHA = .6f; + private static final float FINAL_ALPHA = .65f; private AllAppsContainerView mAppsView; private Workspace mWorkspace; @@ -60,6 +58,7 @@ public class AllAppsTransitionController implements TouchController, VerticalPul private float mCurY; private AnimatorSet mCurrentAnimation; + private boolean mNoIntercept; public AllAppsTransitionController(Launcher launcher) { mLauncher = launcher; @@ -70,11 +69,20 @@ public class AllAppsTransitionController implements TouchController, VerticalPul @Override public boolean onInterceptTouchEvent(MotionEvent ev) { init(); - if (mWorkspace.isInOverviewMode() || mLauncher.isWidgetsViewVisible()) { - return false; - } if (ev.getAction() == MotionEvent.ACTION_DOWN) { - mDetector.setAllAppsState(mLauncher.isAllAppsVisible(), mAppsView.isScrollAtTop()); + mNoIntercept = false; + if (mLauncher.getWorkspace().isInOverviewMode() || mLauncher.isWidgetsViewVisible()) { + mNoIntercept = true; + } + if (mLauncher.isAllAppsVisible() && + !mAppsView.shouldContainerScroll(ev.getX(), ev.getY())) { + mNoIntercept = true; + } + } + if (mNoIntercept) { + return false; + } else { + mDetector.setScrollDirectionDown(mLauncher.isAllAppsVisible()); } mDetector.onTouchEvent(ev); return mDetector.mScrolling; diff --git a/src/com/android/launcher3/allapps/VerticalPullDetector.java b/src/com/android/launcher3/allapps/VerticalPullDetector.java index 12d414e73d..0c3698de28 100644 --- a/src/com/android/launcher3/allapps/VerticalPullDetector.java +++ b/src/com/android/launcher3/allapps/VerticalPullDetector.java @@ -14,9 +14,7 @@ public class VerticalPullDetector { private static final boolean DBG = false; private float mTouchSlop; - - private boolean mAllAppsVisible; - private boolean mAllAppsScrollAtTop; + private boolean mScrollDown; // if false, only scroll up will be reported. /** * The minimum release velocity in pixels per millisecond that triggers fling.. @@ -32,20 +30,20 @@ public class VerticalPullDetector { /* Scroll state, this is set to true during dragging and animation. */ boolean mScrolling; - float mDownX; - float mDownY; - float mDownMillis; + private float mDownX; + private float mDownY; + private float mDownMillis; - float mLastY; - float mLastMillis; + private float mLastY; + private float mLastMillis; - float mVelocity; - float mLastDisplacement; - float mDisplacementY; - float mDisplacementX; + private float mVelocity; + private float mLastDisplacement; + private float mDisplacementY; + private float mDisplacementX; /* scroll started during previous animation */ - boolean mSubtractSlop = true; + private boolean mSubtractSlop = true; /* Client of this gesture detector can register a callback. */ Listener mListener; @@ -67,20 +65,19 @@ public class VerticalPullDetector { mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop(); } - public void setAllAppsState(boolean allAppsVisible, boolean scrollAtTop) { - mAllAppsVisible = allAppsVisible; - mAllAppsScrollAtTop = scrollAtTop; + public void setScrollDirectionDown(boolean scrollDown) { + mScrollDown = scrollDown; } private boolean shouldScrollStart() { float deltaY = Math.abs(mDisplacementY); float deltaX = Math.max(Math.abs(mDisplacementX), 1); - if (mAllAppsVisible && mDisplacementY > mTouchSlop && mAllAppsScrollAtTop) { + if (mScrollDown && mDisplacementY > mTouchSlop) { if (deltaY > deltaX) { return true; } } - if (!mAllAppsVisible && mDisplacementY < -mTouchSlop) { + if (!mScrollDown && mDisplacementY < -mTouchSlop) { if (deltaY > deltaX) { return true; } @@ -140,6 +137,7 @@ public class VerticalPullDetector { private boolean reportScrollStart(boolean recatch) { mListener.onScrollStart(!recatch); + mSubtractSlop = !recatch; if (DBG) { Log.d(TAG, "onScrollStart recatch:" + recatch); } @@ -153,11 +151,15 @@ public class VerticalPullDetector { Log.d(TAG, String.format("onScroll disp=%.1f, velocity=%.1f", mDisplacementY, mVelocity)); } - if (mDisplacementY > 0) { - return mListener.onScroll(mDisplacementY - mTouchSlop, mVelocity); - } else { - return mListener.onScroll(mDisplacementY + mTouchSlop, mVelocity); + float subtractDisplacement = 0f; + if (mSubtractSlop) { + if (mDisplacementY > 0) { + subtractDisplacement = mTouchSlop; + } else { + subtractDisplacement = -mTouchSlop; + } } + return mListener.onScroll(mDisplacementY - subtractDisplacement, mVelocity); } return true; }