From c606bf1af953bb8a682589a29809e714c648c291 Mon Sep 17 00:00:00 2001 From: Daniel Sandler Date: Sun, 28 Oct 2012 00:12:21 -0400 Subject: [PATCH] Improved handle touch interaction. - the handle size is now entirely independent of asset size - the handle doesn't have to have a handle graphic - the handle top/bottom sizing can each change based on whether the challenge is visible - now, the handle becomes very small when the challenge is visible, and does not intrude into the challenge rect itself (so you really need to drag downward through the top edge of the challenge to activate the handle and close the challenge) - when the challenge is closed, the handle may be clicked to open Bug: 7428215 Change-Id: I4ca7b4d5d475337295a6a7492a831abbba288ac5 Proto-Id: Ibc8997ece27ca1e0fa4deb651bb11860f95d7b23 --- .../res/layout-port/keyguard_host_view.xml | 1 - .../impl/keyguard/SlidingChallengeLayout.java | 95 ++++++++++++++----- 2 files changed, 69 insertions(+), 27 deletions(-) diff --git a/core/res/res/layout-port/keyguard_host_view.xml b/core/res/res/layout-port/keyguard_host_view.xml index 15e984443092d..2caa72f000db4 100644 --- a/core/res/res/layout-port/keyguard_host_view.xml +++ b/core/res/res/layout-port/keyguard_host_view.xml @@ -32,7 +32,6 @@ android:id="@+id/sliding_layout" android:layout_width="match_parent" android:layout_height="match_parent" - androidprv:dragHandle="@drawable/kg_security_grip" androidprv:dragIcon="@drawable/kg_security_lock"> 0 ? handleHeight : defaultSize, - iconHeight > 0 ? iconHeight : defaultSize); // top half of the lock icon, plus another 25% to be sure - mDragHandleHeadroom = (int) (iconHeight * 0.75f); - mChallengeBottomBound = (mDragHandleSize + mDragHandleHeadroom + handleHeight) / 2; + mDragHandleClosedAbove = (int) (DRAG_HANDLE_CLOSED_ABOVE * density + 0.5f); + mDragHandleClosedBelow = (int) (DRAG_HANDLE_CLOSED_BELOW * density + 0.5f); + mDragHandleOpenAbove = (int) (DRAG_HANDLE_OPEN_ABOVE * density + 0.5f); + mDragHandleOpenBelow = (int) (DRAG_HANDLE_OPEN_BELOW * density + 0.5f); + + // how much space to account for in the handle when closed + mChallengeBottomBound = + (mDragHandleClosedBelow + mDragHandleClosedAbove + handleHeight) / 2; mHandleDrawable = handle; mDragIconDrawable = icon; @@ -477,9 +499,12 @@ public class SlidingChallengeLayout extends ViewGroup implements ChallengeLayout } mVelocityTracker.addMovement(ev); + //Log.v(TAG, "onIntercept: " + ev); + final int action = ev.getActionMasked(); switch (action) { case MotionEvent.ACTION_DOWN: + mGestureStartX = ev.getX(); mGestureStartY = ev.getY(); mBlockDrag = false; break; @@ -500,7 +525,8 @@ public class SlidingChallengeLayout extends ViewGroup implements ChallengeLayout (isInChallengeView(x, y) && mScrollState == SCROLL_STATE_SETTLING)) && mActivePointerId == INVALID_POINTER) { mActivePointerId = ev.getPointerId(i); - mGestureStartY = ev.getY(); + mGestureStartX = x; + mGestureStartY = y; mGestureStartChallengeBottom = getChallengeBottom(); mDragging = true; } else if (isInChallengeView(x, y)) { @@ -532,10 +558,13 @@ public class SlidingChallengeLayout extends ViewGroup implements ChallengeLayout } mVelocityTracker.addMovement(ev); + //Log.v(TAG, "onTouch: " + ev); + final int action = ev.getActionMasked(); switch (action) { case MotionEvent.ACTION_DOWN: mBlockDrag = false; + mGestureStartX = ev.getX(); mGestureStartY = ev.getY(); break; @@ -551,7 +580,12 @@ public class SlidingChallengeLayout extends ViewGroup implements ChallengeLayout break; } case MotionEvent.ACTION_UP: - if (mDragging) { + if (OPEN_ON_CLICK + && isInDragHandle(mGestureStartX, mGestureStartY) + && Math.abs(ev.getX() - mGestureStartX) <= mTouchSlop + && Math.abs(ev.getY() - mGestureStartY) <= mTouchSlop) { + showChallenge(true); + } else if (mDragging) { mVelocityTracker.computeCurrentVelocity(1000, mMaxVelocity); showChallenge((int) mVelocityTracker.getYVelocity(mActivePointerId)); } @@ -568,6 +602,7 @@ public class SlidingChallengeLayout extends ViewGroup implements ChallengeLayout if ((isInDragHandle(x, y) || crossedDragHandle(x, y, mGestureStartY) || (isInChallengeView(x, y) && mScrollState == SCROLL_STATE_SETTLING)) && mActivePointerId == INVALID_POINTER) { + mGestureStartX = x; mGestureStartY = y; mActivePointerId = ev.getPointerId(i); mGestureStartChallengeBottom = getChallengeBottom(); @@ -605,8 +640,11 @@ public class SlidingChallengeLayout extends ViewGroup implements ChallengeLayout * We only want to add additional vertical space to the drag handle when the panel is fully * closed. */ - private int getDragHandleHeadroom() { - return isChallengeShowing() ? 0 : mDragHandleHeadroom; + private int getDragHandleSizeAbove() { + return isChallengeShowing() ? mDragHandleOpenAbove : mDragHandleClosedAbove; + } + private int getDragHandleSizeBelow() { + return isChallengeShowing() ? mDragHandleOpenBelow : mDragHandleClosedBelow; } private boolean isInChallengeView(float x, float y) { @@ -620,17 +658,17 @@ public class SlidingChallengeLayout extends ViewGroup implements ChallengeLayout if (mChallengeView == null) return false; return x >= mDragHandleEdgeSlop && - y >= mChallengeView.getTop() - getDragHandleHeadroom() && + y >= mChallengeView.getTop() - getDragHandleSizeAbove() && x < getWidth() - mDragHandleEdgeSlop && - y < mChallengeView.getTop() + mDragHandleSize; + y < mChallengeView.getTop() + getDragHandleSizeBelow(); } private boolean crossedDragHandle(float x, float y, float initialY) { final int challengeTop = mChallengeView.getTop(); return x >= 0 && x < getWidth() && - initialY < (challengeTop - getDragHandleHeadroom()) && - y > challengeTop + mDragHandleSize; + initialY < (challengeTop - getDragHandleSizeAbove()) && + y > challengeTop + getDragHandleSizeBelow(); } @Override @@ -760,20 +798,25 @@ public class SlidingChallengeLayout extends ViewGroup implements ChallengeLayout debugPaint.setColor(0x40FF00CC); // show the isInDragHandle() rect c.drawRect(mDragHandleEdgeSlop, - mChallengeView.getTop() - getDragHandleHeadroom(), + mChallengeView.getTop() - getDragHandleSizeAbove(), getWidth() - mDragHandleEdgeSlop, - mChallengeView.getTop() + mDragHandleSize, + mChallengeView.getTop() + getDragHandleSizeBelow(), debugPaint); } - if (mChallengeView != null && mHandleAlpha > 0 && mHandleDrawable != null) { + if (mChallengeView != null && mHandleAlpha > 0) { final int top = mChallengeView.getTop(); - final int handleHeight = mHandleDrawable.getIntrinsicHeight(); + final int handleHeight; final int challengeLeft = mChallengeView.getLeft(); final int challengeRight = mChallengeView.getRight(); - mHandleDrawable.setBounds(challengeLeft, top, challengeRight, top + handleHeight); - mHandleDrawable.setAlpha((int) (mHandleAlpha * 0xFF)); - mHandleDrawable.draw(c); + if (mHandleDrawable != null) { + handleHeight = mHandleDrawable.getIntrinsicHeight(); + mHandleDrawable.setBounds(challengeLeft, top, challengeRight, top + handleHeight); + mHandleDrawable.setAlpha((int) (mHandleAlpha * 0xFF)); + mHandleDrawable.draw(c); + } else { + handleHeight = 0; + } if (DEBUG) { // now show the actual drag handle