Skip to content

Commit c606bf1

Browse files
committed
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
1 parent 950c29e commit c606bf1

File tree

2 files changed

+69
-27
lines changed

2 files changed

+69
-27
lines changed

core/res/res/layout-port/keyguard_host_view.xml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@
3232
android:id="@+id/sliding_layout"
3333
android:layout_width="match_parent"
3434
android:layout_height="match_parent"
35-
androidprv:dragHandle="@drawable/kg_security_grip"
3635
androidprv:dragIcon="@drawable/kg_security_lock">
3736

3837
<FrameLayout

policy/src/com/android/internal/policy/impl/keyguard/SlidingChallengeLayout.java

Lines changed: 69 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import android.content.res.TypedArray;
2222
import android.graphics.Canvas;
2323
import android.graphics.Paint;
24+
import android.graphics.RectF;
2425
import android.graphics.drawable.Drawable;
2526
import android.util.AttributeSet;
2627
import android.util.FloatProperty;
@@ -44,6 +45,18 @@ public class SlidingChallengeLayout extends ViewGroup implements ChallengeLayout
4445
private static final String TAG = "SlidingChallengeLayout";
4546
private static final boolean DEBUG = false;
4647

48+
// The drag handle is measured in dp above & below the top edge of the
49+
// challenge view; these parameters change based on whether the challenge
50+
// is open or closed.
51+
private static final int DRAG_HANDLE_CLOSED_ABOVE = 32; // dp
52+
private static final int DRAG_HANDLE_CLOSED_BELOW = 32; // dp
53+
private static final int DRAG_HANDLE_OPEN_ABOVE = 8; // dp
54+
private static final int DRAG_HANDLE_OPEN_BELOW = 0; // dp
55+
56+
private static final boolean OPEN_ON_CLICK = true;
57+
58+
private static final int HANDLE_ANIMATE_DURATION = 200; // ms
59+
4760
// Drawn to show the drag handle in closed state; crossfades to the challenge view
4861
// when challenge is fully visible
4962
private Drawable mHandleDrawable;
@@ -82,13 +95,20 @@ public class SlidingChallengeLayout extends ViewGroup implements ChallengeLayout
8295
private VelocityTracker mVelocityTracker;
8396
private int mMinVelocity;
8497
private int mMaxVelocity;
85-
private float mGestureStartY; // where did you touch the screen to start this gesture?
98+
private float mGestureStartX, mGestureStartY; // where did you first touch the screen?
8699
private int mGestureStartChallengeBottom; // where was the challenge at that time?
87-
private int mDragHandleSize; // handle hitrect extension into the challenge view
88-
private int mDragHandleHeadroom; // extend the handle's hitrect this far above the line
100+
101+
private int mDragHandleClosedBelow; // handle hitrect extension into the challenge view
102+
private int mDragHandleClosedAbove; // extend the handle's hitrect this far above the line
103+
private int mDragHandleOpenBelow; // handle hitrect extension into the challenge view
104+
private int mDragHandleOpenAbove; // extend the handle's hitrect this far above the line
105+
89106
private int mDragHandleEdgeSlop;
90107
private int mChallengeBottomBound; // Number of pixels from the top of the challenge view
91108
// that should remain on-screen
109+
110+
private int mTouchSlop;
111+
92112
float mHandleAlpha;
93113
float mFrameAlpha;
94114
private ObjectAnimator mHandleAnimation;
@@ -125,9 +145,6 @@ public Float get(SlidingChallengeLayout view) {
125145
}
126146
};
127147

128-
private static final int DRAG_HANDLE_DEFAULT_SIZE = 32; // dp
129-
private static final int HANDLE_ANIMATE_DURATION = 200; // ms
130-
131148
// True if at least one layout pass has happened since the view was attached.
132149
private boolean mHasLayout;
133150

@@ -224,20 +241,25 @@ public SlidingChallengeLayout(Context context, AttributeSet attrs, int defStyle)
224241
mDragHandleEdgeSlop = getResources().getDimensionPixelSize(
225242
R.dimen.kg_edge_swipe_region_size);
226243

244+
mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
245+
227246
setWillNotDraw(false);
228247
}
229248

230249
public void setDragDrawables(Drawable handle, Drawable icon) {
231250
final float density = getResources().getDisplayMetrics().density;
232-
final int defaultSize = (int) (DRAG_HANDLE_DEFAULT_SIZE * density + 0.5f);
233251
final int handleHeight = handle != null ? handle.getIntrinsicHeight() : 0;
234252
final int iconHeight = icon != null ? icon.getIntrinsicHeight() : 0;
235-
mDragHandleSize = Math.max(handleHeight > 0 ? handleHeight : defaultSize,
236-
iconHeight > 0 ? iconHeight : defaultSize);
237253

238254
// top half of the lock icon, plus another 25% to be sure
239-
mDragHandleHeadroom = (int) (iconHeight * 0.75f);
240-
mChallengeBottomBound = (mDragHandleSize + mDragHandleHeadroom + handleHeight) / 2;
255+
mDragHandleClosedAbove = (int) (DRAG_HANDLE_CLOSED_ABOVE * density + 0.5f);
256+
mDragHandleClosedBelow = (int) (DRAG_HANDLE_CLOSED_BELOW * density + 0.5f);
257+
mDragHandleOpenAbove = (int) (DRAG_HANDLE_OPEN_ABOVE * density + 0.5f);
258+
mDragHandleOpenBelow = (int) (DRAG_HANDLE_OPEN_BELOW * density + 0.5f);
259+
260+
// how much space to account for in the handle when closed
261+
mChallengeBottomBound =
262+
(mDragHandleClosedBelow + mDragHandleClosedAbove + handleHeight) / 2;
241263

242264
mHandleDrawable = handle;
243265
mDragIconDrawable = icon;
@@ -477,9 +499,12 @@ public boolean onInterceptTouchEvent(MotionEvent ev) {
477499
}
478500
mVelocityTracker.addMovement(ev);
479501

502+
//Log.v(TAG, "onIntercept: " + ev);
503+
480504
final int action = ev.getActionMasked();
481505
switch (action) {
482506
case MotionEvent.ACTION_DOWN:
507+
mGestureStartX = ev.getX();
483508
mGestureStartY = ev.getY();
484509
mBlockDrag = false;
485510
break;
@@ -500,7 +525,8 @@ public boolean onInterceptTouchEvent(MotionEvent ev) {
500525
(isInChallengeView(x, y) && mScrollState == SCROLL_STATE_SETTLING)) &&
501526
mActivePointerId == INVALID_POINTER) {
502527
mActivePointerId = ev.getPointerId(i);
503-
mGestureStartY = ev.getY();
528+
mGestureStartX = x;
529+
mGestureStartY = y;
504530
mGestureStartChallengeBottom = getChallengeBottom();
505531
mDragging = true;
506532
} else if (isInChallengeView(x, y)) {
@@ -532,10 +558,13 @@ public boolean onTouchEvent(MotionEvent ev) {
532558
}
533559
mVelocityTracker.addMovement(ev);
534560

561+
//Log.v(TAG, "onTouch: " + ev);
562+
535563
final int action = ev.getActionMasked();
536564
switch (action) {
537565
case MotionEvent.ACTION_DOWN:
538566
mBlockDrag = false;
567+
mGestureStartX = ev.getX();
539568
mGestureStartY = ev.getY();
540569
break;
541570

@@ -551,7 +580,12 @@ public boolean onTouchEvent(MotionEvent ev) {
551580
break;
552581
}
553582
case MotionEvent.ACTION_UP:
554-
if (mDragging) {
583+
if (OPEN_ON_CLICK
584+
&& isInDragHandle(mGestureStartX, mGestureStartY)
585+
&& Math.abs(ev.getX() - mGestureStartX) <= mTouchSlop
586+
&& Math.abs(ev.getY() - mGestureStartY) <= mTouchSlop) {
587+
showChallenge(true);
588+
} else if (mDragging) {
555589
mVelocityTracker.computeCurrentVelocity(1000, mMaxVelocity);
556590
showChallenge((int) mVelocityTracker.getYVelocity(mActivePointerId));
557591
}
@@ -568,6 +602,7 @@ public boolean onTouchEvent(MotionEvent ev) {
568602
if ((isInDragHandle(x, y) || crossedDragHandle(x, y, mGestureStartY) ||
569603
(isInChallengeView(x, y) && mScrollState == SCROLL_STATE_SETTLING))
570604
&& mActivePointerId == INVALID_POINTER) {
605+
mGestureStartX = x;
571606
mGestureStartY = y;
572607
mActivePointerId = ev.getPointerId(i);
573608
mGestureStartChallengeBottom = getChallengeBottom();
@@ -605,8 +640,11 @@ public boolean onTouchEvent(MotionEvent ev) {
605640
* We only want to add additional vertical space to the drag handle when the panel is fully
606641
* closed.
607642
*/
608-
private int getDragHandleHeadroom() {
609-
return isChallengeShowing() ? 0 : mDragHandleHeadroom;
643+
private int getDragHandleSizeAbove() {
644+
return isChallengeShowing() ? mDragHandleOpenAbove : mDragHandleClosedAbove;
645+
}
646+
private int getDragHandleSizeBelow() {
647+
return isChallengeShowing() ? mDragHandleOpenBelow : mDragHandleClosedBelow;
610648
}
611649

612650
private boolean isInChallengeView(float x, float y) {
@@ -620,17 +658,17 @@ private boolean isInDragHandle(float x, float y) {
620658
if (mChallengeView == null) return false;
621659

622660
return x >= mDragHandleEdgeSlop &&
623-
y >= mChallengeView.getTop() - getDragHandleHeadroom() &&
661+
y >= mChallengeView.getTop() - getDragHandleSizeAbove() &&
624662
x < getWidth() - mDragHandleEdgeSlop &&
625-
y < mChallengeView.getTop() + mDragHandleSize;
663+
y < mChallengeView.getTop() + getDragHandleSizeBelow();
626664
}
627665

628666
private boolean crossedDragHandle(float x, float y, float initialY) {
629667
final int challengeTop = mChallengeView.getTop();
630668
return x >= 0 &&
631669
x < getWidth() &&
632-
initialY < (challengeTop - getDragHandleHeadroom()) &&
633-
y > challengeTop + mDragHandleSize;
670+
initialY < (challengeTop - getDragHandleSizeAbove()) &&
671+
y > challengeTop + getDragHandleSizeBelow();
634672
}
635673

636674
@Override
@@ -760,20 +798,25 @@ public void draw(Canvas c) {
760798
debugPaint.setColor(0x40FF00CC);
761799
// show the isInDragHandle() rect
762800
c.drawRect(mDragHandleEdgeSlop,
763-
mChallengeView.getTop() - getDragHandleHeadroom(),
801+
mChallengeView.getTop() - getDragHandleSizeAbove(),
764802
getWidth() - mDragHandleEdgeSlop,
765-
mChallengeView.getTop() + mDragHandleSize,
803+
mChallengeView.getTop() + getDragHandleSizeBelow(),
766804
debugPaint);
767805
}
768806

769-
if (mChallengeView != null && mHandleAlpha > 0 && mHandleDrawable != null) {
807+
if (mChallengeView != null && mHandleAlpha > 0) {
770808
final int top = mChallengeView.getTop();
771-
final int handleHeight = mHandleDrawable.getIntrinsicHeight();
809+
final int handleHeight;
772810
final int challengeLeft = mChallengeView.getLeft();
773811
final int challengeRight = mChallengeView.getRight();
774-
mHandleDrawable.setBounds(challengeLeft, top, challengeRight, top + handleHeight);
775-
mHandleDrawable.setAlpha((int) (mHandleAlpha * 0xFF));
776-
mHandleDrawable.draw(c);
812+
if (mHandleDrawable != null) {
813+
handleHeight = mHandleDrawable.getIntrinsicHeight();
814+
mHandleDrawable.setBounds(challengeLeft, top, challengeRight, top + handleHeight);
815+
mHandleDrawable.setAlpha((int) (mHandleAlpha * 0xFF));
816+
mHandleDrawable.draw(c);
817+
} else {
818+
handleHeight = 0;
819+
}
777820

778821
if (DEBUG) {
779822
// now show the actual drag handle

0 commit comments

Comments
 (0)