Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f4cbb142 authored by Hyunyoung Song's avatar Hyunyoung Song
Browse files

Fixes to touch handling in all apps pull up work

b/28917826
- Fast scroll bar works even when it's at the top of the recycler view
- Pull down only happens ONLY IF the thumb of the scroll bar is at top
- When container is touched during sliding down animation,
translation should not jump

Change-Id: Ic1d9a4aa77332cc0a7582556f893053003224dd3
parent a92e0dfa
Loading
Loading
Loading
Loading
+1 −2
Original line number Diff line number Diff line
@@ -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);
+18 −3
Original line number Diff line number Diff line
@@ -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.
+15 −7
Original line number Diff line number Diff line
@@ -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;
+24 −22
Original line number Diff line number Diff line
@@ -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));
            }
            float subtractDisplacement = 0f;
            if (mSubtractSlop) {
                if (mDisplacementY > 0) {
                return mListener.onScroll(mDisplacementY - mTouchSlop, mVelocity);
                    subtractDisplacement = mTouchSlop;
                } else {
                return mListener.onScroll(mDisplacementY + mTouchSlop, mVelocity);
                    subtractDisplacement = -mTouchSlop;
                }
            }
            return mListener.onScroll(mDisplacementY - subtractDisplacement, mVelocity);
        }
        return true;
    }