summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/SystemUI/src/com/android/systemui/SwipeHelper.java15
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/NotificationMenuRow.java107
2 files changed, 79 insertions, 43 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
index 36c38f372b46..ee95254ed26a 100644
--- a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
@@ -50,7 +50,7 @@ public class SwipeHelper implements Gefingerpoken {
public static final int X = 0;
public static final int Y = 1;
- private float SWIPE_ESCAPE_VELOCITY = 100f; // dp/sec
+ private float SWIPE_ESCAPE_VELOCITY = 500f; // dp/sec
private int DEFAULT_ESCAPE_ANIMATION_DURATION = 200; // ms
private int MAX_ESCAPE_ANIMATION_DURATION = 400; // ms
private int MAX_DISMISS_VELOCITY = 4000; // dp/sec
@@ -58,6 +58,9 @@ public class SwipeHelper implements Gefingerpoken {
static final float SWIPE_PROGRESS_FADE_END = 0.5f; // fraction of thumbnail width
// beyond which swipe progress->0
+ public static final float SWIPED_FAR_ENOUGH_SIZE_FRACTION = 0.6f;
+ static final float MAX_SCROLL_SIZE_FRACTION = 0.3f;
+
private float mMinSwipeProgress = 0f;
private float mMaxSwipeProgress = 1f;
@@ -369,9 +372,8 @@ public class SwipeHelper implements Gefingerpoken {
// if the language is rtl we prefer swiping to the left
boolean animateLeftForRtl = velocity == 0 && (getTranslation(animView) == 0 || isDismissAll)
&& isLayoutRtl;
- boolean animateLeft = velocity < 0
- || (velocity == 0 && getTranslation(animView) < 0 && !isDismissAll);
-
+ boolean animateLeft = (Math.abs(velocity) > getEscapeVelocity() && velocity < 0) ||
+ (getTranslation(animView) < 0 && !isDismissAll);
if (animateLeft || animateLeftForRtl || animateUpForMenu) {
newPos = -getSize(animView);
} else {
@@ -590,7 +592,7 @@ public class SwipeHelper implements Gefingerpoken {
// maxScrollDistance
if (CONSTRAIN_SWIPE && !mCallback.canChildBeDismissed(mCurrView)) {
float size = getSize(mCurrView);
- float maxScrollDistance = 0.25f * size;
+ float maxScrollDistance = MAX_SCROLL_SIZE_FRACTION * size;
if (absDelta >= size) {
delta = delta > 0 ? maxScrollDistance : -maxScrollDistance;
} else {
@@ -652,7 +654,8 @@ public class SwipeHelper implements Gefingerpoken {
protected boolean swipedFarEnough() {
float translation = getTranslation(mCurrView);
- return DISMISS_IF_SWIPED_FAR_ENOUGH && Math.abs(translation) > 0.4 * getSize(mCurrView);
+ return DISMISS_IF_SWIPED_FAR_ENOUGH
+ && Math.abs(translation) > SWIPED_FAR_ENOUGH_SIZE_FRACTION * getSize(mCurrView);
}
public boolean isDismissGesture(MotionEvent ev) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMenuRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMenuRow.java
index 7563fd1bf9bf..4305bdef6fef 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMenuRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMenuRow.java
@@ -16,13 +16,13 @@
package com.android.systemui.statusbar;
+import static com.android.systemui.SwipeHelper.SWIPED_FAR_ENOUGH_SIZE_FRACTION;
+
import java.util.ArrayList;
import com.android.systemui.Interpolators;
import com.android.systemui.R;
import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
-import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin.MenuItem;
-import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin.OnMenuEventListener;
import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper;
import com.android.systemui.statusbar.NotificationGuts.GutsContent;
import com.android.systemui.statusbar.stack.NotificationStackScrollLayout;
@@ -46,10 +46,21 @@ import android.widget.FrameLayout.LayoutParams;
public class NotificationMenuRow implements NotificationMenuRowPlugin, View.OnClickListener {
+ private static final boolean DEBUG = false;
+ private static final String TAG = "swipe";
+
private static final int ICON_ALPHA_ANIM_DURATION = 200;
private static final long SHOW_MENU_DELAY = 60;
private static final long SWIPE_MENU_TIMING = 200;
+ // Notification must be swiped at least this fraction of a single menu item to show menu
+ private static final float SWIPED_FAR_ENOUGH_MENU_FRACTION = 0.25f;
+ private static final float SWIPED_FAR_ENOUGH_MENU_UNCLEARABLE_FRACTION = 0.15f;
+
+ // When the menu is displayed, the notification must be swiped within this fraction of a single
+ // menu item to snap back to menu (else it will cover the menu or it'll be dismissed)
+ private static final float SWIPED_BACK_ENOUGH_TO_COVER_FRACTION = 0.2f;
+
private ExpandableNotificationRow mParent;
private Context mContext;
@@ -78,6 +89,7 @@ public class NotificationMenuRow implements NotificationMenuRowPlugin, View.OnCl
private int mIconPadding;
private float mAlpha = 0f;
+ private float mPrevX;
private CheckForDrag mCheckForDrag;
private Handler mHandler;
@@ -203,14 +215,14 @@ public class NotificationMenuRow implements NotificationMenuRowPlugin, View.OnCl
}
mHandler.removeCallbacks(mCheckForDrag);
mCheckForDrag = null;
+ mPrevX = ev.getRawX();
break;
case MotionEvent.ACTION_MOVE:
mSnapping = false;
- // If the menu is visible and the movement is towards it it's not a location change.
- boolean locationChange = isTowardsMenu(mTranslation)
- ? false : isMenuLocationChange();
- if (locationChange) {
+ float diffX = ev.getRawX() - mPrevX;
+ mPrevX = ev.getRawX();
+ if (!isTowardsMenu(diffX) && isMenuLocationChange()) {
// Don't consider it "snapped" if location has changed.
mMenuSnappedTo = false;
@@ -262,36 +274,53 @@ public class NotificationMenuRow implements NotificationMenuRowPlugin, View.OnCl
final double timeForGesture = ev.getEventTime() - ev.getDownTime();
final boolean showMenuForSlowOnGoing = !mParent.canViewBeDismissed()
&& timeForGesture >= SWIPE_MENU_TIMING;
+ final float menuSnapTarget = mOnLeft ? getSpaceForMenu() : -getSpaceForMenu();
+
+ if (DEBUG) {
+ Log.d(TAG, "mTranslation= " + mTranslation
+ + " mAlpha= " + mAlpha
+ + " velocity= " + velocity
+ + " mMenuSnappedTo= " + mMenuSnappedTo
+ + " mMenuSnappedOnLeft= " + mMenuSnappedOnLeft
+ + " mOnLeft= " + mOnLeft
+ + " minDismissVel= " + mSwipeHelper.getMinDismissVelocity()
+ + " isDismissGesture= " + mSwipeHelper.isDismissGesture(ev)
+ + " gestureTowardsMenu= " + gestureTowardsMenu
+ + " gestureFastEnough= " + gestureFastEnough
+ + " gestureFarEnough= " + gestureFarEnough);
+ }
- final float targetLeft = mOnLeft ? getSpaceForMenu() : -getSpaceForMenu();
- if (mMenuSnappedTo && isMenuVisible()) {
- if (mMenuSnappedOnLeft == mOnLeft) {
- boolean coveringMenu = Math.abs(mTranslation) <= getSpaceForMenu() * 0.6f;
- if (gestureTowardsMenu || coveringMenu) {
- // Gesture is towards or covering the menu or a dismiss
- snapBack(animView, 0);
- } else if (mSwipeHelper.isDismissGesture(ev)) {
- dismiss(animView, velocity);
- } else {
- // Didn't move enough to dismiss or cover, snap to the menu
- showMenu(animView, targetLeft, velocity);
- }
- } else if ((!gestureFastEnough && swipedEnoughToShowMenu())
- || (gestureTowardsMenu && !gestureFarEnough)) {
- // The menu has been snapped to previously, however, the menu is now on the
- // other side. If gesture is towards menu and not too far snap to the menu.
- showMenu(animView, targetLeft, velocity);
- } else if (mSwipeHelper.isDismissGesture(ev)) {
+ if (mMenuSnappedTo && isMenuVisible() && mMenuSnappedOnLeft == mOnLeft) {
+ // Menu was snapped to previously and we're on the same side, figure out if
+ // we should stick to the menu, snap back into place, or dismiss
+ final float maximumSwipeDistance = mHorizSpaceForIcon
+ * SWIPED_BACK_ENOUGH_TO_COVER_FRACTION;
+ final float targetLeft = getSpaceForMenu() - maximumSwipeDistance;
+ final float targetRight = mParent.getWidth() * SWIPED_FAR_ENOUGH_SIZE_FRACTION;
+ boolean withinSnapMenuThreshold = mOnLeft
+ ? mTranslation > targetLeft && mTranslation < targetRight
+ : mTranslation < -targetLeft && mTranslation > -targetRight;
+ boolean shouldSnapTo = mOnLeft ? mTranslation < targetLeft : mTranslation > -targetLeft;
+ if (DEBUG) {
+ Log.d(TAG, " withinSnapMenuThreshold= " + withinSnapMenuThreshold
+ + " shouldSnapTo= " + shouldSnapTo
+ + " targetLeft= " + targetLeft
+ + " targetRight= " + targetRight);
+ }
+ if (withinSnapMenuThreshold && !mSwipeHelper.isDismissGesture(ev)) {
+ // Haven't moved enough to unsnap from the menu
+ showMenu(animView, menuSnapTarget, velocity);
+ } else if (mSwipeHelper.isDismissGesture(ev) && !shouldSnapTo) {
+ // Only dismiss if we're not moving towards the menu
dismiss(animView, velocity);
} else {
snapBack(animView, velocity);
}
- } else if (((!gestureFastEnough || showMenuForSlowOnGoing)
- && swipedEnoughToShowMenu())
- || gestureTowardsMenu) {
+ } else if ((swipedEnoughToShowMenu() && (!gestureFastEnough || showMenuForSlowOnGoing))
+ || (gestureTowardsMenu && !mSwipeHelper.isDismissGesture(ev))) {
// Menu has not been snapped to previously and this is menu revealing gesture
- showMenu(animView, targetLeft, velocity);
- } else if (mSwipeHelper.isDismissGesture(ev)) {
+ showMenu(animView, menuSnapTarget, velocity);
+ } else if (mSwipeHelper.isDismissGesture(ev) && !gestureTowardsMenu) {
dismiss(animView, velocity);
} else {
snapBack(animView, velocity);
@@ -326,14 +355,18 @@ public class NotificationMenuRow implements NotificationMenuRowPlugin, View.OnCl
mSwipeHelper.dismiss(animView, velocity);
}
+ /**
+ * @return whether the notification has been translated enough to show the menu and not enough
+ * to be dismissed.
+ */
private boolean swipedEnoughToShowMenu() {
- // If the notification can't be dismissed then how far it can move is
- // restricted -- reduce the distance it needs to move in this case.
- final float multiplier = mParent.canViewBeDismissed() ? 0.4f : 0.2f;
- final float snapBackThreshold = getSpaceForMenu() * multiplier;
- return !mSwipeHelper.swipedFarEnough(0, 0) && isMenuVisible() && (mOnLeft
- ? mTranslation > snapBackThreshold
- : mTranslation < -snapBackThreshold);
+ final float multiplier = mParent.canViewBeDismissed()
+ ? SWIPED_FAR_ENOUGH_MENU_FRACTION
+ : SWIPED_FAR_ENOUGH_MENU_UNCLEARABLE_FRACTION;
+ final float minimumSwipeDistance = mHorizSpaceForIcon * multiplier;
+ return !mSwipeHelper.swipedFarEnough(0, 0) && isMenuVisible()
+ && (mOnLeft ? mTranslation > minimumSwipeDistance
+ : mTranslation < -minimumSwipeDistance);
}
/**