summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Adam Cohen <adamcohen@google.com> 2012-10-28 18:29:17 -0700
committer Adam Cohen <adamcohen@google.com> 2012-10-28 18:44:54 -0700
commite3643138c89d49a01ba6a622ffaf71c9a95d5cdc (patch)
tree343f6004cb14f20169b1f4644785778390394854
parentb317db4c5c32ad419a777986bd97a659af1142d2 (diff)
Implementing new slider / widget interaction where frame goes around the widget
-> Frame resizes dynamically as the security slides -> Widget shrinks immediately as the handle begins being brought up -> Widget grows only upon security settling in the down position -> Cleaned up a lot of state interaction between the security slider and the widget pager / pages -> Loosened long press slop (was using Euclidean distance by accident instead of x crossed or y crossed logic) Change-Id: Ic52b62e577c539327b0a65c9277300fc626cf190
-rw-r--r--policy/src/com/android/internal/policy/impl/keyguard/CheckLongPressHelper.java6
-rw-r--r--policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewStateManager.java99
-rw-r--r--policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetFrame.java89
-rw-r--r--policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetPager.java13
-rw-r--r--policy/src/com/android/internal/policy/impl/keyguard/MultiPaneChallengeLayout.java1
-rw-r--r--policy/src/com/android/internal/policy/impl/keyguard/SlidingChallengeLayout.java10
6 files changed, 165 insertions, 53 deletions
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/CheckLongPressHelper.java b/policy/src/com/android/internal/policy/impl/keyguard/CheckLongPressHelper.java
index 020fdbabb64b..4825e23ec9c9 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/CheckLongPressHelper.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/CheckLongPressHelper.java
@@ -60,8 +60,10 @@ public class CheckLongPressHelper {
public void onMove(MotionEvent ev) {
float x = ev.getX();
float y = ev.getY();
+ boolean xMoved = Math.abs(mDownX - x) > mScaledTouchSlop;
+ boolean yMoved = Math.abs(mDownY - y) > mScaledTouchSlop;
- if (Math.sqrt(Math.pow(mDownX - x, 2) + Math.pow(mDownY - y, 2)) > mScaledTouchSlop) {
+ if (xMoved || yMoved) {
cancelLongPress();
}
}
@@ -77,4 +79,4 @@ public class CheckLongPressHelper {
public boolean hasPerformedLongPress() {
return mHasPerformedLongPress;
}
-} \ No newline at end of file
+}
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewStateManager.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewStateManager.java
index 806c6f096fee..fb7bebaa5b85 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewStateManager.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewStateManager.java
@@ -22,7 +22,6 @@ import android.view.View;
public class KeyguardViewStateManager implements SlidingChallengeLayout.OnChallengeScrolledListener {
private KeyguardWidgetPager mPagedView;
- private int mCurrentPageIndex;
private ChallengeLayout mChallengeLayout;
private Runnable mHideHintsRunnable;
private KeyguardSecurityView mKeyguardSecurityContainer;
@@ -31,6 +30,12 @@ public class KeyguardViewStateManager implements SlidingChallengeLayout.OnChalle
private static final int SCREEN_ON_RING_HINT_DELAY = 300;
Handler mMainQueue = new Handler(Looper.myLooper());
+ int mLastScrollState = SlidingChallengeLayout.SCROLL_STATE_IDLE;
+
+ // Paged view state
+ private int mPageListeningToSlider = -1;
+ private int mCurrentPage = -1;
+
int mChallengeTop = 0;
public KeyguardViewStateManager() {
@@ -66,28 +71,39 @@ public class KeyguardViewStateManager implements SlidingChallengeLayout.OnChalle
}
public void onPageSwitch(View newPage, int newPageIndex) {
- // Reset the previous page size and ensure the current page is sized appropriately
- if (mPagedView != null) {
- KeyguardWidgetFrame oldPage = mPagedView.getWidgetPageAt(mCurrentPageIndex);
- // Reset the old widget page to full size
- if (oldPage != null) {
- oldPage.resetSize();
+ // Reset the previous page size and ensure the current page is sized appropriately.
+ // We only modify the page state if it is not currently under control by the slider.
+ // This prevents conflicts.
+ if (mPagedView != null && mChallengeLayout != null) {
+ KeyguardWidgetFrame prevPage = mPagedView.getWidgetPageAt(mCurrentPage);
+ if (prevPage != null && mCurrentPage != mPageListeningToSlider) {
+ prevPage.resetSize();
}
KeyguardWidgetFrame newCurPage = mPagedView.getWidgetPageAt(newPageIndex);
- if (mChallengeLayout.isChallengeOverlapping()) {
- sizeWidgetFrameToChallengeTop(newCurPage);
+ boolean challengeOverlapping = mChallengeLayout.isChallengeOverlapping();
+ if (challengeOverlapping && !newCurPage.isSmall()
+ && mPageListeningToSlider != newPageIndex) {
+ shrinkWidget(newCurPage);
}
}
- mCurrentPageIndex = newPageIndex;
+ mCurrentPage = newPageIndex;
}
- private void sizeWidgetFrameToChallengeTop(KeyguardWidgetFrame frame) {
- if (frame == null) return;
+ private int getChallengeTopRelativeToFrame(KeyguardWidgetFrame frame, int top) {
mTmpPoint[0] = 0;
- mTmpPoint[1] = mChallengeTop;
+ mTmpPoint[1] = top;
mapPoint((View) mChallengeLayout, frame, mTmpPoint);
- frame.setChallengeTop(mTmpPoint[1]);
+ return mTmpPoint[1];
+ }
+
+ private void shrinkWidget(KeyguardWidgetFrame frame) {
+ if (frame != null && mChallengeLayout != null &&
+ mChallengeLayout instanceof SlidingChallengeLayout) {
+ SlidingChallengeLayout scl = (SlidingChallengeLayout) mChallengeLayout;
+ int top = scl.getMaxChallengeTop();
+ frame.shrinkWidget(getChallengeTopRelativeToFrame(frame, top));
+ }
}
/**
@@ -114,20 +130,17 @@ public class KeyguardViewStateManager implements SlidingChallengeLayout.OnChalle
@Override
public void onScrollStateChanged(int scrollState) {
+ if (mPagedView == null || mChallengeLayout == null) return;
+ boolean challengeOverlapping = mChallengeLayout.isChallengeOverlapping();
+
if (scrollState == SlidingChallengeLayout.SCROLL_STATE_IDLE) {
- if (mPagedView == null) return;
+ KeyguardWidgetFrame frame = mPagedView.getWidgetPageAt(mPageListeningToSlider);
+ if (frame == null) return;
- boolean challengeOverlapping = mChallengeLayout.isChallengeOverlapping();
- int curPage = mPagedView.getCurrentPage();
- KeyguardWidgetFrame frame = mPagedView.getWidgetPageAt(curPage);
-
- if (frame != null) {
- if (!challengeOverlapping) {
- frame.resetSize();
- } else {
- sizeWidgetFrameToChallengeTop(frame);
- }
+ if (!challengeOverlapping) {
+ frame.resetSize();
}
+ frame.hideFrame(this);
if (challengeOverlapping) {
mPagedView.setOnlyAllowEdgeSwipes(true);
@@ -140,10 +153,38 @@ public class KeyguardViewStateManager implements SlidingChallengeLayout.OnChalle
} else {
mKeyguardSecurityContainer.onPause();
}
- } else {
+ mPageListeningToSlider = -1;
+ } else if (mLastScrollState == SlidingChallengeLayout.SCROLL_STATE_IDLE) {
+ // Whether dragging or settling, if the last state was idle, we use this signal
+ // to update the current page who will receive events from the sliding challenge.
+ // We resize the frame as appropriate.
+ mPageListeningToSlider = mPagedView.getNextPage();
+ KeyguardWidgetFrame frame = mPagedView.getWidgetPageAt(mPageListeningToSlider);
+ if (frame == null) return;
+
+ frame.showFrame(this);
+
+ // As soon as the security begins sliding, the widget becomes small (if it wasn't
+ // small to begin with).
+ if (!frame.isSmall()) {
+ // We need to fetch the final page, in case the pages are in motion.
+ mPageListeningToSlider = mPagedView.getNextPage();
+ System.out.println("Shrink widget from scroll state changed!");
+ shrinkWidget(frame);
+ }
// View is on the move. Pause the security view until it completes.
mKeyguardSecurityContainer.onPause();
}
+ mLastScrollState = scrollState;
+ }
+
+ @Override
+ public void onScrollPositionChanged(float scrollPosition, int challengeTop) {
+ mChallengeTop = challengeTop;
+ KeyguardWidgetFrame frame = mPagedView.getWidgetPageAt(mPageListeningToSlider);
+ if (frame != null) {
+ frame.adjustFrame(getChallengeTopRelativeToFrame(frame, mChallengeTop));
+ }
}
public void showUsabilityHints() {
@@ -164,10 +205,4 @@ public class KeyguardViewStateManager implements SlidingChallengeLayout.OnChalle
mMainQueue.postDelayed(mHideHintsRunnable, SCREEN_ON_HINT_DURATION);
}
-
- @Override
- public void onScrollPositionChanged(float scrollPosition, int challengeTop) {
- mChallengeTop = challengeTop;
- }
-
}
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetFrame.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetFrame.java
index 20e86ad5475d..b03e0c5afeea 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetFrame.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetFrame.java
@@ -16,6 +16,9 @@
package com.android.internal.policy.impl.keyguard;
+import android.animation.Animator;
+import android.animation.ObjectAnimator;
+import android.animation.PropertyValuesHolder;
import android.appwidget.AppWidgetHostView;
import android.content.Context;
import android.content.res.Resources;
@@ -49,6 +52,8 @@ public class KeyguardWidgetFrame extends FrameLayout {
private final Rect mForegroundRect = new Rect();
private int mForegroundAlpha = 0;
private CheckLongPressHelper mLongPressHelper;
+ private Animator mFrameFade;
+ private boolean mIsSmall = false;
private float mBackgroundAlpha;
private float mContentAlpha;
@@ -56,6 +61,11 @@ public class KeyguardWidgetFrame extends FrameLayout {
private Drawable mBackgroundDrawable;
private Rect mBackgroundRect = new Rect();
+ // Multiple callers may try and adjust the alpha of the frame. When a caller shows
+ // the outlines, we give that caller control, and nobody else can fade them out.
+ // This prevents animation conflicts.
+ private Object mBgAlphaController;
+
public KeyguardWidgetFrame(Context context) {
this(context, null, 0);
}
@@ -81,6 +91,11 @@ public class KeyguardWidgetFrame extends FrameLayout {
}
@Override
+ protected void onDetachedFromWindow() {
+ cancelLongPress();
+ }
+
+ @Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
// Watch for longpress events at this level to make sure
// users can always pick up this widget
@@ -238,11 +253,28 @@ public class KeyguardWidgetFrame extends FrameLayout {
}
/**
+ * Set the top location of the challenge.
+ *
+ * @param top The top of the challenge, in _local_ coordinates, or -1 to indicate the challenge
+ * is down.
+ */
+ private void setChallengeTop(int top, boolean updateWidgetSize) {
+ // The widget starts below the padding, and extends to the top of the challengs.
+ int widgetHeight = top - getPaddingTop();
+ int frameHeight = top + getPaddingBottom();
+ setFrameHeight(frameHeight);
+ if (updateWidgetSize) {
+ setWidgetHeight(widgetHeight);
+ }
+ }
+
+ /**
* Depending on whether the security is up, the widget size needs to change
*
* @param height The height of the widget, -1 for full height
*/
- public void setWidgetHeight(int height) {
+ private void setWidgetHeight(int height) {
+ System.out.println("Set widget height: " + this + " : " + height);
boolean needLayout = false;
View widget = getContent();
if (widget != null) {
@@ -257,22 +289,56 @@ public class KeyguardWidgetFrame extends FrameLayout {
}
}
- /**
- * Set the top location of the challenge.
- *
- * @param top The top of the challenge, in _local_ coordinates, or -1 to indicate the challenge
- * is down.
- */
- public void setChallengeTop(int top) {
- // The widget starts below the padding, and extends to the top of the challengs.
- int widgetHeight = top - getPaddingTop();
- setWidgetHeight(widgetHeight);
+ public boolean isSmall() {
+ return mIsSmall;
+ }
+
+ public void adjustFrame(int challengeTop) {
+ setChallengeTop(challengeTop, false);
+ }
+
+ public void shrinkWidget(int challengeTop) {
+ mIsSmall = true;
+ setChallengeTop(challengeTop, true);
}
public void resetSize() {
+ mIsSmall = false;
+ setFrameHeight(getMeasuredHeight());
setWidgetHeight(LayoutParams.MATCH_PARENT);
}
+ public void setFrameHeight(int height) {
+ height = Math.min(height, getMeasuredHeight());
+ mBackgroundRect.set(0, 0, getMeasuredWidth(), height);
+ invalidate();
+ }
+
+ public void hideFrame(Object caller) {
+ fadeFrame(caller, false, 0f, 150);
+ }
+
+ public void showFrame(Object caller) {
+ fadeFrame(caller, true, 1f, 150);
+ }
+
+ public void fadeFrame(Object caller, boolean takeControl, float alpha, int duration) {
+ if (takeControl) {
+ mBgAlphaController = caller;
+ }
+
+ if (mBgAlphaController != caller) return;
+
+ if (mFrameFade != null) {
+ mFrameFade.cancel();
+ mFrameFade = null;
+ }
+ PropertyValuesHolder bgAlpha = PropertyValuesHolder.ofFloat("backgroundAlpha", alpha);
+ mFrameFade = ObjectAnimator.ofPropertyValuesHolder(this, bgAlpha);
+ mFrameFade.setDuration(duration);
+ mFrameFade.start();
+ }
+
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
@@ -285,6 +351,7 @@ public class KeyguardWidgetFrame extends FrameLayout {
mRightToLeftGradient = new LinearGradient(x1, 0f, x0, 0f,
mGradientColor, 0, Shader.TileMode.CLAMP);
mBackgroundRect.set(0, 0, w, h);
+ invalidate();
}
void setOverScrollAmount(float r, boolean left) {
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetPager.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetPager.java
index 09ce4db4e10b..539cdd1fcaad 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetPager.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetPager.java
@@ -433,9 +433,11 @@ public class KeyguardWidgetPager extends PagedView implements PagedView.PageSwit
int count = getChildCount();
PropertyValuesHolder alpha;
- PropertyValuesHolder outlineAlpha;
ArrayList<Animator> anims = new ArrayList<Animator>();
+ int duration = show ? CHILDREN_OUTLINE_FADE_IN_DURATION :
+ CHILDREN_OUTLINE_FADE_OUT_DURATION;
+
int curPage = getNextPage();
for (int i = 0; i < count; i++) {
float finalContentAlpha;
@@ -446,16 +448,15 @@ public class KeyguardWidgetPager extends PagedView implements PagedView.PageSwit
} else {
finalContentAlpha = 0f;
}
- float finalOutlineAlpha = show ? getAlphaForPage(mScreenCenter, i) : 0f;
KeyguardWidgetFrame child = getWidgetPageAt(i);
alpha = PropertyValuesHolder.ofFloat("contentAlpha", finalContentAlpha);
- outlineAlpha = PropertyValuesHolder.ofFloat("backgroundAlpha",finalOutlineAlpha);
- ObjectAnimator a = ObjectAnimator.ofPropertyValuesHolder(child, alpha, outlineAlpha);
+ ObjectAnimator a = ObjectAnimator.ofPropertyValuesHolder(child, alpha);
anims.add(a);
+
+ float finalOutlineAlpha = show ? getAlphaForPage(mScreenCenter, i) : 0f;
+ child.fadeFrame(this, show, finalOutlineAlpha, duration);
}
- int duration = show ? CHILDREN_OUTLINE_FADE_IN_DURATION :
- CHILDREN_OUTLINE_FADE_OUT_DURATION;
mChildrenOutlineFadeAnimation = new AnimatorSet();
mChildrenOutlineFadeAnimation.playTogether(anims);
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/MultiPaneChallengeLayout.java b/policy/src/com/android/internal/policy/impl/keyguard/MultiPaneChallengeLayout.java
index 3ccc7ea55ef8..a207f5d1048d 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/MultiPaneChallengeLayout.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/MultiPaneChallengeLayout.java
@@ -20,7 +20,6 @@ import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Rect;
import android.util.AttributeSet;
-import android.util.Log;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
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 304171c28dab..3cd097fbbee6 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/SlidingChallengeLayout.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/SlidingChallengeLayout.java
@@ -374,7 +374,7 @@ public class SlidingChallengeLayout extends ViewGroup implements ChallengeLayout
mScrollState = state;
animateHandle(state == SCROLL_STATE_IDLE && !mChallengeShowing);
- animateFrame(state != SCROLL_STATE_IDLE, false);
+ animateFrame(false , false);
if (mScrollListener != null) {
mScrollListener.onScrollStateChanged(state);
}
@@ -845,6 +845,14 @@ public class SlidingChallengeLayout extends ViewGroup implements ChallengeLayout
}
}
+ public int getMaxChallengeTop() {
+ if (mChallengeView == null) return 0;
+
+ final int layoutBottom = getLayoutBottom();
+ final int challengeHeight = mChallengeView.getHeight();
+ return layoutBottom - challengeHeight;
+ }
+
/**
* Move the bottom edge of mChallengeView to a new position and notify the listener
* if it represents a change in position. Changes made through this method will