From 6f35209e728a7a9a56afbbdefd3d7bfa1e05ea73 Mon Sep 17 00:00:00 2001 From: Adam Powell Date: Thu, 25 Oct 2012 20:49:32 -0700 Subject: [PATCH] Integrate assets from UX; drag/bouncer animation behavior in slider Integrated changes from prototype app Change-Id: I5f017431531b6d12aca89a674d865402c60c2104 --- .../drawable-hdpi/kg_bouncer_bg_white.9.png | Bin 0 -> 219 bytes .../res/drawable-hdpi/kg_security_grip.9.png | Bin 0 -> 233 bytes .../res/drawable-hdpi/kg_security_lock.png | Bin 0 -> 1898 bytes .../drawable-mdpi/kg_bouncer_bg_white.9.png | Bin 0 -> 186 bytes .../res/drawable-mdpi/kg_security_grip.9.png | Bin 0 -> 197 bytes .../res/drawable-mdpi/kg_security_lock.png | Bin 0 -> 1530 bytes .../drawable-xhdpi/kg_bouncer_bg_white.9.png | Bin 0 -> 240 bytes .../res/drawable-xhdpi/kg_security_grip.9.png | Bin 0 -> 263 bytes .../res/drawable-xhdpi/kg_security_lock.png | Bin 0 -> 2484 bytes .../res/layout-port/keyguard_host_view.xml | 9 +- core/res/res/values/attrs.xml | 1 + .../impl/keyguard/SlidingChallengeLayout.java | 140 +++++++++++++++--- 12 files changed, 124 insertions(+), 26 deletions(-) create mode 100644 core/res/res/drawable-hdpi/kg_bouncer_bg_white.9.png create mode 100644 core/res/res/drawable-hdpi/kg_security_grip.9.png create mode 100644 core/res/res/drawable-hdpi/kg_security_lock.png create mode 100644 core/res/res/drawable-mdpi/kg_bouncer_bg_white.9.png create mode 100644 core/res/res/drawable-mdpi/kg_security_grip.9.png create mode 100644 core/res/res/drawable-mdpi/kg_security_lock.png create mode 100644 core/res/res/drawable-xhdpi/kg_bouncer_bg_white.9.png create mode 100644 core/res/res/drawable-xhdpi/kg_security_grip.9.png create mode 100644 core/res/res/drawable-xhdpi/kg_security_lock.png diff --git a/core/res/res/drawable-hdpi/kg_bouncer_bg_white.9.png b/core/res/res/drawable-hdpi/kg_bouncer_bg_white.9.png new file mode 100644 index 0000000000000000000000000000000000000000..c34fe207fcae219b22efcf4bc9231b484e28938c GIT binary patch literal 219 zcmeAS@N?(olHy`uVBq!ia0vp^Y9P$P1|(P5zFY^SSc;uILpXq-h9ji|$mcBZh%9Dc z;O+!rM)Q-W*8&A=JzX3_B3j?xFyv}55NUoW{?YB;ndSzmEU2Do!QeAT+>X)OdI8WO44$rjF6*2UngDL~OZ@-< literal 0 HcmV?d00001 diff --git a/core/res/res/drawable-hdpi/kg_security_grip.9.png b/core/res/res/drawable-hdpi/kg_security_grip.9.png new file mode 100644 index 0000000000000000000000000000000000000000..fb1c86655b5f6ce5afe972be7ff0391e860efffc GIT binary patch literal 233 zcmeAS@N?(olHy`uVBq!ia0vp^7C_9(!3HD+lJs+d6icy_X9x!n)NrJ90QsB+9+AZi z4BVX{%xHe{^je@`x2KC^h(+(+OJ}o~7Xcvn^d8a&^gK zRn0$zeXP?ejz~${Jl?wVsQ2-C8(!T}m0R^H*DUql)V->1*)umK#NLcf+A_^6>6P|h cag~+Ey;lr>J-Jvn3+OBcPgg&ebxsLQ0GvZxz5oCK literal 0 HcmV?d00001 diff --git a/core/res/res/drawable-hdpi/kg_security_lock.png b/core/res/res/drawable-hdpi/kg_security_lock.png new file mode 100644 index 0000000000000000000000000000000000000000..136d3adfa80d24eef807b42040410a0c57dbdb18 GIT binary patch literal 1898 zcmZ`)doYwf+BTqg%RS*e3k003Dk zg+zxCvuAJ#=yns`%7y?IY)i8Rps_%D$4?ycMdIjoM8F+8^bvA20w{DE0Lj__WMl#G z4GLxa1waB+<&!S}gj)b8N0)avTS5;K{=e9f!0z6u>b`#iibzIN+~Xjm{MX3C;Z{%< zfl9J<2@x!v@v?WZQ~VLM(Ufx4bjPseMaTX-mj9+4dCaaN9*Jn6ZJ&~AwEA+%#{S?R zIA=-iEyU{m=MDk z-;|QCd>_OwGYKBstSB>yGm`EqZaGjQ`xEJA#ObM{9-N&@ryxUvSG|?O*6fkq#N}x{ zhUc4q1@Nv>j|WZAM0@?+O~qs1MVmd7l9ujQxl`xSmTW;F=$~5=q}njX{R?=)qo^x9 zVKvhbAG7=8yP&qVcArovGyzPl{kCaoR^9)E$jHc4_4XdwT%HjECX03Nn2JoAS^@7n zDbOhli=%BDD8O-%vpvVH_vcpKzn?wZ9=A_SOe|_>t2y|2&Aof#1?tCR5eOrno}Cy& zCAEe_if@8F;Rqx#5Gyz5ub<%oV_NbDOw- z+0XveIke6w3*~!;Ab}|4F766C5*|GbLe|yQjfv=@(c%a!c#^yxc8R+ffM1{ub8AE8 zp;icFGTGr;US2ty&HnTnw-n_8%gW2C4egg!Ho7U|OB#Io^l5oa&)vH)QdV`frrg_# zt*tG!k`o>A)3{M5j7kKZ(eimP7r9|LaKUOeWnf@nv^JC+VH1z4X>V`$5jp?c97YEf zA?PyS1}Xu@;x)a!yCYioVcaOi(a|yAzPP!$xjg4dDBJTD&ggWokI!srZRnUzzH)bW z_wC`vYotE^n__S0qQ4g9r{2g3iI4wcF_Kxnyd3#!TbmB*1)rbG=esL7%OU1IzPgX5 zrd%Xezj*$}_?@h*EPtOy#RD$a=uJZEWb1~WdV%~A^Vs)dBO{+t>SzVvN< zvDiSo&rOQttf-t4vupw|w9~(*4PfZk#&M$#IhC(RC-s++1`^jJQ>8SG4|3`fdi=p6 zO(4n)r%LvDN839(#ywa(*XcFfk%#3EiDhP3CX`xc+GzOk@Y;d3;GTucQnPoIE@_KTNmB(XP~-&r&!O85tSl?Jby4x*-ZCa7&T8ir;R;{oszb zM!deHu;yLgHYNP$P!S&7Dx|!p8!B<;%Tr_qUa&bFi+Zn4dWS)wF1=zYw9Yv$z045_%!y>F08=$taRrK5WCYImT{{_TG4T9%zA>IA%S zqk$rwfxhBzu3=qjcvUMH4zNRkoW7BI4|?uM(|}6ADQ%r*WT;EiP_8bSw9B6#{$^@& z7Unu6BFrkYg;`FWbg_oKGC6YOE_Yk}3PtE;ywEt6K~ zTF?HO2CK@;&#zeBx}a0|K?W9>E{`#coG+(w@Q3?QuTD8Tztrq{V!>h@dbBS~f$$jV z4o4)0sq+AHGc`%h4DZ;wnc)QkGor#ij()aC^jPut?M>yK6<4h-LuB-`<`5~6oE(im$&3&5i)Rr6Vp$LXV+__9jm4miO4nJ zaCd?*qxs3xYk`6>o-U3d9-YZQ{{OdUmV96@BE0;^|9UnzjmJEe+XT5KBqe)iW@IuN zB{)7754`!uPNF%_PHJn$l|_NwZn|K`!6d=RwZcU@i?}7~)+!wP|NpFVdQ&MBb@0L=P1&j0`b literal 0 HcmV?d00001 diff --git a/core/res/res/drawable-mdpi/kg_security_grip.9.png b/core/res/res/drawable-mdpi/kg_security_grip.9.png new file mode 100644 index 0000000000000000000000000000000000000000..25beb2b08ef2b981252d2c6b29b4cb6409222acf GIT binary patch literal 197 zcmeAS@N?(olHy`uVBq!ia0vp^YCz1w!3HEBMfy$#af+QhLpXq-h9ji|$mcBZh%9Dc z;O+!rM)Q-W*8&C8JzX3_G$x+CxR8s9k%9Sw`9$sMI$Xb$|J8pr7vYt15pdZNsW+R4 zk1d(!*ojgRR!vFvP literal 0 HcmV?d00001 diff --git a/core/res/res/drawable-mdpi/kg_security_lock.png b/core/res/res/drawable-mdpi/kg_security_lock.png new file mode 100644 index 0000000000000000000000000000000000000000..861760da8d1b9358c71de67398199484173be2e4 GIT binary patch literal 1530 zcmZ`(c{tQt7(PVFa;db*MbaP_gJ_y$YnU+@HOews8q7%3G#FzUOO&M&>Dp&#lr425 zWv1K6GBkOF>M85h#$*{XbnQ#rpZm}K>ptiC&ikG3ocDR3?>XnZ*H7ZmO7d#*001RN z3f())0T{ds08AJF2}uAf zL#2c<02pup#?JwO%m-k1NFo1}CA6{G-wBNZ>l>rEz9I{%Yz@J9(ILeA8xCz0D@g9O zBg*!)XG^`u6vfSBPyA;(J%&apoV;Oek)$Nle#voLeSGww=B(z)JK~I>Ys<&G%cfSfQo$bIL9h(IfpuMs+SQ|md(q4AK|k= zYkv~2p{Z%j4HY?T0+KI{emQavbcWipbPt=D2r5sHmxx+#UEZy@Sy}4q_JF;hK5k_` zFEKIEt+TW9`me_#-c|Y3xsy*&C};%hnlKZib10YT7*#3~iTs$Q{TJuo2DE0#N@=O3--ua|NCC;m z=LfFI6%`dtJn8>VSGKmWm`~P?5K0gIh^j#6<0?{*pJn(M`?J~Xv|((;2W#e{SS;pY zrBMg>+g(F)?#JriBzdiIj(+L0v0uB;F&$^zgU5PZ4EO1s@^+c?EuQ`%Y6S@xogr8E z8<|Fa4bGp(<7dZC9rfO(`Acf(V6!Y}l6)q@>gebQk2dH2Hoil|K5GL;H(I9q1V8WREg@S|J0XMHB-H}f zN=gW3y*q5Em*gpOlGc82?(*RjN#(X9sx(;5`9o4LYntX){L*N;2)Y$9%>xu?hh^h& zcYSgMyEtXISHrx)usWMkeB~PSrjC15c`pTCx^(HWVsDtblha9iJtpdS*nU1#YKNPG}~`!hv4dP)DJ`%^*;)w6r9Xppu(Q?7vT_)THfkK&Yi_ zfXppgXa@(YBZ{JTSOkTU03MeIQ)wblSPZw;mEk+yLX9g34{}JiO#UA0)gOL`o1H@6U&!Z8+os5 znvhdi_Xo6{_Ym~;obP_IVUjb0?rxKiy&Vj<_Y4mthLey1VI&BEDcr==&;)L1YJS=T zfiyQq9yT+CA3?(5CJg3=`~F9u(gK6Y(f?1d(QD>IguNRIZZvXuBr%KxYy)ZjBrQiO aF^GgG5d)(`+ejN83>@uos4Ba2SN;LCbiRoI literal 0 HcmV?d00001 diff --git a/core/res/res/drawable-xhdpi/kg_bouncer_bg_white.9.png b/core/res/res/drawable-xhdpi/kg_bouncer_bg_white.9.png new file mode 100644 index 0000000000000000000000000000000000000000..9c4a603f6756d27bf8d448e4eb4b1a33df91bce3 GIT binary patch literal 240 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 etmF{x7epqI{YVLvZt{=m2{_m| + androidprv:dragHandle="@drawable/kg_security_grip" + androidprv:dragIcon="@drawable/kg_security_lock"> + android:layout_marginLeft="@dimen/kg_edge_swipe_region_size" + android:layout_marginRight="@dimen/kg_edge_swipe_region_size" + android:background="@drawable/kg_bouncer_bg_white" + android:gravity="bottom|center_horizontal"> + diff --git a/policy/src/com/android/internal/policy/impl/keyguard/SlidingChallengeLayout.java b/policy/src/com/android/internal/policy/impl/keyguard/SlidingChallengeLayout.java index 165fbe73d38e1..26e0fecef6ce6 100644 --- a/policy/src/com/android/internal/policy/impl/keyguard/SlidingChallengeLayout.java +++ b/policy/src/com/android/internal/policy/impl/keyguard/SlidingChallengeLayout.java @@ -16,12 +16,15 @@ package com.android.internal.policy.impl.keyguard; +import android.animation.ObjectAnimator; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Canvas; import android.graphics.drawable.Drawable; import android.util.AttributeSet; +import android.util.FloatProperty; import android.util.Log; +import android.util.Property; import android.view.MotionEvent; import android.view.VelocityTracker; import android.view.View; @@ -42,7 +45,8 @@ public class SlidingChallengeLayout extends ViewGroup implements ChallengeLayout // Drawn to show the drag handle in closed state; crossfades to the challenge view // when challenge is fully visible private Drawable mHandleDrawable; - private boolean mShowHandle = true; + private Drawable mFrameDrawable; + private Drawable mDragIconDrawable; // Initialized during measurement from child layoutparams private View mChallengeView; @@ -79,8 +83,44 @@ public class SlidingChallengeLayout extends ViewGroup implements ChallengeLayout private float mLastTouchY; private int mDragHandleSize; private int mDragHandleEdgeSlop; + float mHandleAlpha; + float mFrameAlpha; + private ObjectAnimator mHandleAnimation; + private ObjectAnimator mFrameAnimation; + + static final Property HANDLE_ALPHA = + new FloatProperty("handleAlpha") { + @Override + public void setValue(SlidingChallengeLayout view, float value) { + view.mHandleAlpha = value; + view.invalidate(); + } + + @Override + public Float get(SlidingChallengeLayout view) { + return view.mHandleAlpha; + } + }; + + static final Property FRAME_ALPHA = + new FloatProperty("frameAlpha") { + @Override + public void setValue(SlidingChallengeLayout view, float value) { + if (view.mFrameDrawable != null) { + view.mFrameAlpha = value; + view.mFrameDrawable.setAlpha((int) (value * 0xFF)); + view.mFrameDrawable.invalidateSelf(); + } + } + + @Override + public Float get(SlidingChallengeLayout view) { + return view.mFrameAlpha; + } + }; private static final int DRAG_HANDLE_DEFAULT_SIZE = 32; // dp + private static final int HANDLE_ANIMATE_DURATION = 200; // ms // True if at least one layout pass has happened since the view was attached. private boolean mHasLayout; @@ -164,7 +204,8 @@ public class SlidingChallengeLayout extends ViewGroup implements ChallengeLayout final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.SlidingChallengeLayout, defStyle, 0); - setDragHandleDrawable(a.getDrawable(R.styleable.SlidingChallengeLayout_dragHandle)); + setDragDrawables(a.getDrawable(R.styleable.SlidingChallengeLayout_dragHandle), + a.getDrawable(R.styleable.SlidingChallengeLayout_dragIcon)); a.recycle(); @@ -180,15 +221,53 @@ public class SlidingChallengeLayout extends ViewGroup implements ChallengeLayout setWillNotDraw(false); } - public void setDragHandleDrawable(Drawable d) { - if (d != null) { - mDragHandleSize = d.getIntrinsicHeight(); + public void setDragDrawables(Drawable handle, Drawable icon) { + final float density = getResources().getDisplayMetrics().density; + final int defaultSize = (int) (DRAG_HANDLE_DEFAULT_SIZE * density + 0.5f); + mDragHandleSize = Math.max(handle != null ? handle.getIntrinsicHeight() : defaultSize, + icon != null ? icon.getIntrinsicHeight() : defaultSize); + mHandleDrawable = handle; + mDragIconDrawable = icon; + } + + public void setDragIconDrawable(Drawable d) { + mDragIconDrawable = d; + } + + public void showHandle(boolean visible) { + if (visible) { + if (mHandleAnimation != null) { + mHandleAnimation.cancel(); + mHandleAnimation = null; + } + mHandleAlpha = 1.f; + invalidate(); + } else { + animateHandle(false); } - if (mDragHandleSize == 0 || d == null) { - final float density = getResources().getDisplayMetrics().density; - mDragHandleSize = (int) (DRAG_HANDLE_DEFAULT_SIZE * density + 0.5f); + } + + void animateHandle(boolean visible) { + if (mHandleAnimation != null) { + mHandleAnimation.cancel(); } - mHandleDrawable = d; + mHandleAnimation = ObjectAnimator.ofFloat(this, HANDLE_ALPHA, visible ? 1.f : 0.f); + mHandleAnimation.setInterpolator(sHandleFadeInterpolator); + mHandleAnimation.setDuration(HANDLE_ANIMATE_DURATION); + mHandleAnimation.start(); + } + + void animateFrame(boolean visible, boolean full) { + if (mFrameDrawable == null) return; + + if (mFrameAnimation != null) { + mFrameAnimation.cancel(); + } + mFrameAnimation = ObjectAnimator.ofFloat(this, FRAME_ALPHA, + visible ? (full ? 1.f : 0.5f) : 0.f); + mFrameAnimation.setInterpolator(sHandleFadeInterpolator); + mFrameAnimation.setDuration(HANDLE_ANIMATE_DURATION); + mFrameAnimation.start(); } private void sendInitialListenerUpdates() { @@ -249,6 +328,8 @@ public class SlidingChallengeLayout extends ViewGroup implements ChallengeLayout if (mScrollState != state) { mScrollState = state; + animateHandle(state == SCROLL_STATE_IDLE && !mChallengeShowing); + animateFrame(state == SCROLL_STATE_DRAGGING, false); if (mScrollListener != null) { mScrollListener.onScrollStateChanged(state); } @@ -342,8 +423,9 @@ public class SlidingChallengeLayout extends ViewGroup implements ChallengeLayout showChallenge(true); mIsBouncing = true; if (mScrimView != null) { - mScrimView.setVisibility(GONE); + mScrimView.setVisibility(VISIBLE); } + animateFrame(true, true); if (mBouncerListener != null) { mBouncerListener.onBouncerStateChanged(true); } @@ -357,6 +439,7 @@ public class SlidingChallengeLayout extends ViewGroup implements ChallengeLayout if (mScrimView != null) { mScrimView.setVisibility(GONE); } + animateFrame(false, false); if (mBouncerListener != null) { mBouncerListener.onBouncerStateChanged(false); } @@ -393,7 +476,8 @@ public class SlidingChallengeLayout extends ViewGroup implements ChallengeLayout final float x = ev.getX(i); final float y = ev.getY(i); - if ((isInDragHandle(x, y) || crossedDragHandle(x, y, mLastTouchY) || + if (!mIsBouncing && + (isInDragHandle(x, y) || crossedDragHandle(x, y, mLastTouchY) || (isInChallengeView(x, y) && mScrollState == SCROLL_STATE_SETTLING)) && mActivePointerId == INVALID_POINTER) { mActivePointerId = ev.getPointerId(i); @@ -450,7 +534,7 @@ public class SlidingChallengeLayout extends ViewGroup implements ChallengeLayout break; case MotionEvent.ACTION_MOVE: - if (!mDragging && !mBlockDrag) { + if (!mDragging && !mBlockDrag && !mIsBouncing) { final int count = ev.getPointerCount(); for (int i = 0; i < count; i++) { final float x = ev.getX(i); @@ -543,6 +627,9 @@ public class SlidingChallengeLayout extends ViewGroup implements ChallengeLayout if (mChallengeView != oldChallengeView) { mChallengeView.setVisibility(mChallengeShowing ? VISIBLE : INVISIBLE); } + // We're going to play silly games with the frame's background drawable later. + mFrameDrawable = mChallengeView.getBackground(); + mFrameDrawable.setAlpha(0); } else if (lp.childType == LayoutParams.CHILD_TYPE_SCRIM) { setScrimView(child); } @@ -603,8 +690,8 @@ public class SlidingChallengeLayout extends ViewGroup implements ChallengeLayout sendInitialListenerUpdates(); } }); + mHasLayout = true; } - mHasLayout = true; } public void computeScroll() { @@ -630,13 +717,25 @@ public class SlidingChallengeLayout extends ViewGroup implements ChallengeLayout @Override public void draw(Canvas c) { super.draw(c); - if (mChallengeOffset < 1.f - && mChallengeView != null && mHandleDrawable != null && mShowHandle) { + if (mChallengeView != null && mHandleAlpha > 0 && mHandleDrawable != null) { final int top = mChallengeView.getTop(); - mHandleDrawable.setBounds(0, top, getWidth(), top + mDragHandleSize); - final float alpha = sHandleFadeInterpolator.getInterpolation(1 - mChallengeOffset); - mHandleDrawable.setAlpha((int) (alpha * 0xFF)); + final int handleHeight = mHandleDrawable.getIntrinsicHeight(); + 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 (mDragIconDrawable != null) { + final int iconWidth = mDragIconDrawable.getIntrinsicWidth(); + final int iconHeight = mDragIconDrawable.getIntrinsicHeight(); + final int iconLeft = (challengeLeft + challengeRight - iconWidth) / 2; + final int iconTop = top + (handleHeight - iconHeight) / 2; + mDragIconDrawable.setBounds(iconLeft, iconTop, iconLeft + iconWidth, + iconTop + iconHeight); + mDragIconDrawable.setAlpha((int) (mHandleAlpha * 0xFF)); + mDragIconDrawable.draw(c); + } } } @@ -730,11 +829,6 @@ public class SlidingChallengeLayout extends ViewGroup implements ChallengeLayout } } - public void showHandle(boolean show) { - mShowHandle = show; - invalidate(); - } - @Override public ViewGroup.LayoutParams generateLayoutParams(AttributeSet attrs) { return new LayoutParams(getContext(), attrs);