diff --git a/packages/SystemUI/res/drawable/ic_clear_all.xml b/packages/SystemUI/res/drawable/ic_clear_all.xml
new file mode 100644
index 0000000000000..b0f3a5a46c993
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_clear_all.xml
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
+
diff --git a/packages/SystemUI/res/layout/status_bar_notification_dismiss_all.xml b/packages/SystemUI/res/layout/status_bar_notification_dismiss_all.xml
new file mode 100644
index 0000000000000..515270a97292e
--- /dev/null
+++ b/packages/SystemUI/res/layout/status_bar_notification_dismiss_all.xml
@@ -0,0 +1,40 @@
+
+
+
+
+
+
diff --git a/packages/SystemUI/res/layout/super_status_bar.xml b/packages/SystemUI/res/layout/super_status_bar.xml
index 6f64e1721ba7c..ac998f69ca0de 100644
--- a/packages/SystemUI/res/layout/super_status_bar.xml
+++ b/packages/SystemUI/res/layout/super_status_bar.xml
@@ -54,7 +54,8 @@
+ android:layout_height="match_parent"
+ android:background="@color/transparent" >
4dp
+
+ 4dp
+
48dp
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 416cd542932c3..5d4b536db5170 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -732,6 +732,9 @@
Don\'t show again
+
+ Clear all
+
Start now
diff --git a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
index d153d09766f45..6e1ba3c3d532b 100644
--- a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
@@ -21,6 +21,7 @@ import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.animation.ValueAnimator.AnimatorUpdateListener;
+import android.content.Context;
import android.graphics.RectF;
import android.os.Handler;
import android.util.Log;
@@ -29,6 +30,8 @@ import android.view.VelocityTracker;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.accessibility.AccessibilityEvent;
+import android.view.animation.AnimationUtils;
+import android.view.animation.Interpolator;
import android.view.animation.LinearInterpolator;
public class SwipeHelper implements Gefingerpoken {
@@ -44,6 +47,7 @@ public class SwipeHelper implements Gefingerpoken {
public static final int Y = 1;
private static LinearInterpolator sLinearInterpolator = new LinearInterpolator();
+ private final Interpolator mFastOutLinearInInterpolator;
private float SWIPE_ESCAPE_VELOCITY = 100f; // dp/sec
private int DEFAULT_ESCAPE_ANIMATION_DURATION = 200; // ms
@@ -76,16 +80,17 @@ public class SwipeHelper implements Gefingerpoken {
private Runnable mWatchLongPress;
private long mLongPressTimeout;
- public SwipeHelper(int swipeDirection, Callback callback, float densityScale,
- float pagingTouchSlop) {
+ public SwipeHelper(int swipeDirection, Callback callback, Context context) {
mCallback = callback;
mHandler = new Handler();
mSwipeDirection = swipeDirection;
mVelocityTracker = VelocityTracker.obtain();
- mDensityScale = densityScale;
- mPagingTouchSlop = pagingTouchSlop;
+ mDensityScale = context.getResources().getDisplayMetrics().density;
+ mPagingTouchSlop = ViewConfiguration.get(context).getScaledPagingTouchSlop();
mLongPressTimeout = (long) (ViewConfiguration.getLongPressTimeout() * 1.5f); // extra long-press!
+ mFastOutLinearInInterpolator = AnimationUtils.loadInterpolator(context,
+ android.R.interpolator.fast_out_linear_in);
}
public void setLongPressListener(View.OnLongClickListener listener) {
@@ -277,6 +282,19 @@ public class SwipeHelper implements Gefingerpoken {
* @param velocity The desired pixels/second speed at which the view should move
*/
public void dismissChild(final View view, float velocity) {
+ dismissChild(view, velocity, null, 0, false, 0);
+ }
+
+ /**
+ * @param view The view to be dismissed
+ * @param velocity The desired pixels/second speed at which the view should move
+ * @param endAction The action to perform at the end
+ * @param delay The delay after which we should start
+ * @param useAccelerateInterpolator Should an accelerating Interpolator be used
+ * @param fixedDuration If not 0, this exact duration will be taken
+ */
+ public void dismissChild(final View view, float velocity, final Runnable endAction,
+ long delay, boolean useAccelerateInterpolator, long fixedDuration) {
final View animView = mCallback.getChildContentView(view);
final boolean canAnimViewBeDismissed = mCallback.canChildBeDismissed(view);
float newPos;
@@ -289,22 +307,38 @@ public class SwipeHelper implements Gefingerpoken {
} else {
newPos = getSize(animView);
}
- int duration = MAX_ESCAPE_ANIMATION_DURATION;
- if (velocity != 0) {
- duration = Math.min(duration,
- (int) (Math.abs(newPos - getTranslation(animView)) * 1000f / Math
- .abs(velocity)));
+ long duration;
+ if (fixedDuration == 0) {
+ duration = MAX_ESCAPE_ANIMATION_DURATION;
+ if (velocity != 0) {
+ duration = Math.min(duration,
+ (int) (Math.abs(newPos - getTranslation(animView)) * 1000f / Math
+ .abs(velocity))
+ );
+ } else {
+ duration = DEFAULT_ESCAPE_ANIMATION_DURATION;
+ }
} else {
- duration = DEFAULT_ESCAPE_ANIMATION_DURATION;
+ duration = fixedDuration;
}
animView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
ObjectAnimator anim = createTranslationAnimation(animView, newPos);
- anim.setInterpolator(sLinearInterpolator);
+ if (useAccelerateInterpolator) {
+ anim.setInterpolator(mFastOutLinearInInterpolator);
+ } else {
+ anim.setInterpolator(sLinearInterpolator);
+ }
anim.setDuration(duration);
+ if (delay > 0) {
+ anim.setStartDelay(delay);
+ }
anim.addListener(new AnimatorListenerAdapter() {
public void onAnimationEnd(Animator animation) {
mCallback.onChildDismissed(view);
+ if (endAction != null) {
+ endAction.run();
+ }
animView.setLayerType(View.LAYER_TYPE_NONE, null);
}
});
diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsHorizontalScrollView.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsHorizontalScrollView.java
index 72a33410747f3..25a62ae819fbf 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/RecentsHorizontalScrollView.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsHorizontalScrollView.java
@@ -56,9 +56,7 @@ public class RecentsHorizontalScrollView extends HorizontalScrollView
public RecentsHorizontalScrollView(Context context, AttributeSet attrs) {
super(context, attrs, 0);
- float densityScale = getResources().getDisplayMetrics().density;
- float pagingTouchSlop = ViewConfiguration.get(getContext()).getScaledPagingTouchSlop();
- mSwipeHelper = new SwipeHelper(SwipeHelper.Y, this, densityScale, pagingTouchSlop);
+ mSwipeHelper = new SwipeHelper(SwipeHelper.Y, this, context);
mFadedEdgeDrawHelper = FadedEdgeDrawHelper.create(context, attrs, this, false);
mRecycledViews = new HashSet();
}
diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsVerticalScrollView.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsVerticalScrollView.java
index 1213375c83f4b..e8e9d529e2469 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/RecentsVerticalScrollView.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsVerticalScrollView.java
@@ -56,9 +56,7 @@ public class RecentsVerticalScrollView extends ScrollView
public RecentsVerticalScrollView(Context context, AttributeSet attrs) {
super(context, attrs, 0);
- float densityScale = getResources().getDisplayMetrics().density;
- float pagingTouchSlop = ViewConfiguration.get(getContext()).getScaledPagingTouchSlop();
- mSwipeHelper = new SwipeHelper(SwipeHelper.X, this, densityScale, pagingTouchSlop);
+ mSwipeHelper = new SwipeHelper(SwipeHelper.X, this, context);
mFadedEdgeDrawHelper = FadedEdgeDrawHelper.create(context, attrs, this, true);
mRecycledViews = new HashSet();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index 04fc02c3c78d1..a2595bf254ead 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -192,6 +192,7 @@ public abstract class BaseStatusBar extends SystemUI implements
protected boolean mShowLockscreenNotifications;
protected NotificationOverflowContainer mKeyguardIconOverflowContainer;
+ protected DismissView mDismissView;
public boolean isDeviceProvisioned() {
return mDeviceProvisioned;
@@ -1330,9 +1331,12 @@ public abstract class BaseStatusBar extends SystemUI implements
} else {
mKeyguardIconOverflowContainer.setVisibility(View.GONE);
}
- // Move overflow container to last position.
+ // Move overflow container to second last position.
mStackScroller.changeViewPosition(mKeyguardIconOverflowContainer,
- mStackScroller.getChildCount() - 1);
+ mStackScroller.getChildCount() - 2);
+
+ // Now move dismissView to the last position.
+ mStackScroller.changeViewPosition(mDismissView, mStackScroller.getChildCount() - 1);
}
private boolean shouldShowOnKeyguard(StatusBarNotification sbn) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/DismissView.java b/packages/SystemUI/src/com/android/systemui/statusbar/DismissView.java
new file mode 100644
index 0000000000000..6cc1a575a87db
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/DismissView.java
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.systemui.statusbar;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.view.View;
+import android.view.animation.AnimationUtils;
+import android.view.animation.Interpolator;
+import android.view.animation.PathInterpolator;
+import android.widget.Button;
+import android.widget.TextView;
+import com.android.systemui.R;
+
+public class DismissView extends ExpandableView {
+
+ private Button mClearAllText;
+ private boolean mIsVisible;
+ private final Interpolator mAppearInterpolator = new PathInterpolator(0f, 0.2f, 1f, 1f);
+ private final Interpolator mDisappearInterpolator = new PathInterpolator(0f, 0f, 0.8f, 1f);
+
+ public DismissView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ @Override
+ protected void onFinishInflate() {
+ super.onFinishInflate();
+ mClearAllText = (Button) findViewById(R.id.dismiss_text);
+ setInvisible();
+ }
+
+ @Override
+ protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+ super.onLayout(changed, left, top, right, bottom);
+ setOutlineProvider(null);
+ }
+
+ @Override
+ public boolean isTransparent() {
+ return true;
+ }
+
+ public void performVisibilityAnimation(boolean nowVisible) {
+ animateText(nowVisible, null /* onFinishedRunnable */);
+ }
+
+ public void performVisibilityAnimation(boolean nowVisible, Runnable onFinishedRunnable) {
+ animateText(nowVisible, onFinishedRunnable);
+ }
+
+ /**
+ * Animate the text to a new visibility.
+ *
+ * @param nowVisible should it now be visible
+ * @param onFinishedRunnable A runnable which should be run when the animation is
+ * finished.
+ */
+ public void animateText(boolean nowVisible, Runnable onFinishedRunnable) {
+ if (nowVisible != mIsVisible) {
+ // Animate text
+ float endValue = nowVisible ? 1.0f : 0.0f;
+ Interpolator interpolator;
+ if (nowVisible) {
+ interpolator = mAppearInterpolator;
+ } else {
+ interpolator = mDisappearInterpolator;
+ }
+ mClearAllText.animate()
+ .alpha(endValue)
+ .setInterpolator(interpolator)
+ .withEndAction(onFinishedRunnable)
+ .setDuration(260)
+ .withLayer();
+ mIsVisible = nowVisible;
+ } else {
+ if (onFinishedRunnable != null) {
+ onFinishedRunnable.run();
+ }
+ }
+ }
+
+ public void setInvisible() {
+ mClearAllText.setAlpha(0.0f);
+ mIsVisible = false;
+ }
+
+ @Override
+ public void performRemoveAnimation(float translationDirection, Runnable onFinishedRunnable) {
+ performVisibilityAnimation(false);
+ }
+
+ @Override
+ public void performAddAnimation(long delay) {
+ performVisibilityAnimation(true);
+ }
+
+ @Override
+ public void setScrimAmount(float scrimAmount) {
+ // We don't need to scrim the dismissView
+ }
+
+ public void setOnButtonClickListener(OnClickListener onClickListener) {
+ mClearAllText.setOnClickListener(onClickListener);
+ }
+
+ @Override
+ public boolean hasOverlappingRendering() {
+ return false;
+ }
+
+ public void cancelAnimation() {
+ mClearAllText.animate().cancel();
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index acfdb06ac66a5..13fad7b34d3d4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -118,6 +118,7 @@ import com.android.systemui.qs.QSTile;
import com.android.systemui.statusbar.ActivatableNotificationView;
import com.android.systemui.statusbar.BaseStatusBar;
import com.android.systemui.statusbar.CommandQueue;
+import com.android.systemui.statusbar.DismissView;
import com.android.systemui.statusbar.DragDownHelper;
import com.android.systemui.statusbar.ExpandableNotificationRow;
import com.android.systemui.statusbar.GestureRecorder;
@@ -676,6 +677,15 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
SpeedBumpView speedBump = (SpeedBumpView) LayoutInflater.from(mContext).inflate(
R.layout.status_bar_notification_speed_bump, mStackScroller, false);
mStackScroller.setSpeedBumpView(speedBump);
+ mDismissView = (DismissView) LayoutInflater.from(mContext).inflate(
+ R.layout.status_bar_notification_dismiss_all, mStackScroller, false);
+ mDismissView.setOnButtonClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ clearAllNotifications();
+ }
+ });
+ mStackScroller.setDismissView(mDismissView);
mExpandedContents = mStackScroller;
mScrimController = new ScrimController(mStatusBarWindow.findViewById(R.id.scrim_behind),
@@ -828,6 +838,73 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
return mStatusBarView;
}
+ private void clearAllNotifications() {
+
+ // animate-swipe all dismissable notifications, then animate the shade closed
+ int numChildren = mStackScroller.getChildCount();
+
+ final ArrayList viewsToHide = new ArrayList(numChildren);
+ for (int i = 0; i < numChildren; i++) {
+ final View child = mStackScroller.getChildAt(i);
+ if (mStackScroller.canChildBeDismissed(child)) {
+ if (child.getVisibility() == View.VISIBLE) {
+ viewsToHide.add(child);
+ }
+ }
+ }
+ if (viewsToHide.isEmpty()) {
+ animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_NONE);
+ return;
+ }
+
+ mPostCollapseCleanup = new Runnable() {
+ @Override
+ public void run() {
+ try {
+ mBarService.onClearAllNotifications(mCurrentUserId);
+ } catch (Exception ex) { }
+ }
+ };
+
+ performDismissAllAnimations(viewsToHide);
+
+ }
+
+ private void performDismissAllAnimations(ArrayList hideAnimatedList) {
+ Runnable animationFinishAction = new Runnable() {
+ @Override
+ public void run() {
+ mStackScroller.post(new Runnable() {
+ @Override
+ public void run() {
+ mStackScroller.setDismissAllInProgress(false);
+ }
+ });
+ animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_NONE);
+ }
+ };
+
+ // let's disable our normal animations
+ mStackScroller.setDismissAllInProgress(true);
+
+ // Decrease the delay for every row we animate to give the sense of
+ // accelerating the swipes
+ int rowDelayDecrement = 10;
+ int currentDelay = 140;
+ int totalDelay = 0;
+ int numItems = hideAnimatedList.size();
+ for (int i = 0; i < numItems; i++) {
+ View view = hideAnimatedList.get(i);
+ Runnable endRunnable = null;
+ if (i == numItems - 1) {
+ endRunnable = animationFinishAction;
+ }
+ mStackScroller.dismissViewAnimated(view, endRunnable, totalDelay, 260);
+ currentDelay = Math.max(50, currentDelay - rowDelayDecrement);
+ totalDelay += currentDelay;
+ }
+ }
+
/**
* Hack to improve glyph rasterization for scaled text views.
*/
@@ -1338,10 +1415,32 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
}
updateRowStates();
updateSpeedbump();
+ updateClearAll();
+
mNotificationPanel.setQsExpansionEnabled(provisioned && mUserSetup);
mShadeUpdates.check();
}
+ private void updateClearAll() {
+ boolean showDismissView = false;
+ if (mState != StatusBarState.KEYGUARD) {
+ for (int i = 0; i < mNotificationData.size(); i++) {
+ Entry entry = mNotificationData.get(i);
+ if (entry.row.getParent() == null) {
+ // This view isn't even added, so the stack scroller doesn't
+ // know about it. Ignore completely.
+ continue;
+ }
+ if (entry.row.getVisibility() != View.GONE && entry.expanded != null
+ && entry.notification.isClearable()) {
+ showDismissView = true;
+ break;
+ }
+ }
+ }
+ mStackScroller.updateDismissView(showDismissView);
+ }
+
private void updateSpeedbump() {
int speedbumpIndex = -1;
int currentIndex = 0;
@@ -2021,6 +2120,10 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
public void animateCollapsePanels(int flags, boolean force) {
if (!force &&
(mState == StatusBarState.KEYGUARD || mState == StatusBarState.SHADE_LOCKED)) {
+ if (mPostCollapseCleanup != null) {
+ mPostCollapseCleanup.run();
+ mPostCollapseCleanup = null;
+ }
return;
}
if (SPEW) {
@@ -3446,6 +3549,10 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
}
public void onTrackingStarted() {
+ if (mPostCollapseCleanup != null) {
+ mPostCollapseCleanup.run();
+ mPostCollapseCleanup = null;
+ }
}
public void onUnlockHintStarted() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpNotificationView.java
index f3ff8ad7b092a..ac260dbb39a99 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpNotificationView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpNotificationView.java
@@ -176,11 +176,9 @@ public class HeadsUpNotificationView extends FrameLayout implements SwipeHelper.
@Override
public void onAttachedToWindow() {
- float densityScale = getResources().getDisplayMetrics().density;
final ViewConfiguration viewConfiguration = ViewConfiguration.get(getContext());
- float pagingTouchSlop = viewConfiguration.getScaledPagingTouchSlop();
float touchSlop = viewConfiguration.getScaledTouchSlop();
- mSwipeHelper = new SwipeHelper(SwipeHelper.X, this, densityScale, pagingTouchSlop);
+ mSwipeHelper = new SwipeHelper(SwipeHelper.X, this, getContext());
mSwipeHelper.setMaxSwipeProgress(mMaxAlpha);
mEdgeSwipeHelper = new EdgeSwipeHelper(touchSlop);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
index 9bcffd1b17356..079cb88ebc705 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
@@ -35,6 +35,7 @@ import com.android.systemui.ExpandHelper;
import com.android.systemui.R;
import com.android.systemui.SwipeHelper;
import com.android.systemui.statusbar.ActivatableNotificationView;
+import com.android.systemui.statusbar.DismissView;
import com.android.systemui.statusbar.ExpandableNotificationRow;
import com.android.systemui.statusbar.ExpandableView;
import com.android.systemui.statusbar.SpeedBumpView;
@@ -139,6 +140,8 @@ public class NotificationStackScrollLayout extends ViewGroup
private boolean mExpandingNotification;
private boolean mExpandedInThisMotion;
private boolean mScrollingEnabled;
+ private DismissView mDismissView;
+ private boolean mDismissAllInProgress;
/**
* Was the scroller scrolled to the top when the down motion was observed?
@@ -172,6 +175,7 @@ public class NotificationStackScrollLayout extends ViewGroup
private boolean mInterceptDelegateEnabled;
private boolean mDelegateToScrollView;
private boolean mDisallowScrollingInThisMotion;
+ private boolean mDismissWillBeGone;
private ViewTreeObserver.OnPreDrawListener mChildrenUpdater
= new ViewTreeObserver.OnPreDrawListener() {
@@ -238,7 +242,7 @@ public class NotificationStackScrollLayout extends ViewGroup
mOverflingDistance = configuration.getScaledOverflingDistance();
float densityScale = getResources().getDisplayMetrics().density;
float pagingTouchSlop = ViewConfiguration.get(getContext()).getScaledPagingTouchSlop();
- mSwipeHelper = new SwipeHelper(SwipeHelper.X, this, densityScale, pagingTouchSlop);
+ mSwipeHelper = new SwipeHelper(SwipeHelper.X, this, getContext());
mSwipeHelper.setLongPressListener(mLongClickListener);
mSidePaddings = context.getResources()
@@ -481,6 +485,9 @@ public class NotificationStackScrollLayout extends ViewGroup
}
public void onChildDismissed(View v) {
+ if (mDismissAllInProgress) {
+ return;
+ }
if (DEBUG) Log.v(TAG, "onChildDismissed: " + v);
final View veto = v.findViewById(R.id.veto);
if (veto != null && veto.getVisibility() != View.GONE) {
@@ -627,8 +634,9 @@ public class NotificationStackScrollLayout extends ViewGroup
initView(getContext());
}
- public void dismissRowAnimated(View child, int vel) {
- mSwipeHelper.dismissChild(child, vel);
+ public void dismissViewAnimated(View child, Runnable endRunnable, int delay, long duration) {
+ child.setClipBounds(null);
+ mSwipeHelper.dismissChild(child, 0, endRunnable, delay, true, duration);
}
@Override
@@ -1526,12 +1534,13 @@ public class NotificationStackScrollLayout extends ViewGroup
* @param newIndex the new index
*/
public void changeViewPosition(View child, int newIndex) {
- if (child != null && child.getParent() == this) {
+ int currentIndex = indexOfChild(child);
+ if (child != null && child.getParent() == this && currentIndex != newIndex) {
mChangePositionInProgress = true;
removeView(child);
addView(child, newIndex);
mChangePositionInProgress = false;
- if (mIsExpanded && mAnimationsEnabled) {
+ if (mIsExpanded && mAnimationsEnabled && child.getVisibility() != View.GONE) {
mChildrenChangingPositions.add(child);
mNeedsAnimation = true;
}
@@ -1918,7 +1927,8 @@ public class NotificationStackScrollLayout extends ViewGroup
}
public void goToFullShade() {
- updateSpeedBump(true);
+ updateSpeedBump(true /* visibility */);
+ mDismissView.setInvisible();
}
public void cancelExpandHelper() {
@@ -1962,6 +1972,40 @@ public class NotificationStackScrollLayout extends ViewGroup
requestChildrenUpdate();
}
+ public void setDismissView(DismissView dismissView) {
+ mDismissView = dismissView;
+ addView(mDismissView);
+ }
+
+ public void updateDismissView(boolean visible) {
+ int oldVisibility = mDismissWillBeGone ? GONE : mDismissView.getVisibility();
+ int newVisibility = visible ? VISIBLE : GONE;
+ if (oldVisibility != newVisibility) {
+ if (oldVisibility == GONE) {
+ if (mDismissWillBeGone) {
+ mDismissView.cancelAnimation();
+ } else {
+ mDismissView.setInvisible();
+ mDismissView.setVisibility(newVisibility);
+ }
+ mDismissWillBeGone = false;
+ } else {
+ mDismissWillBeGone = true;
+ mDismissView.performVisibilityAnimation(false, new Runnable() {
+ @Override
+ public void run() {
+ mDismissView.setVisibility(GONE);
+ mDismissWillBeGone = false;
+ }
+ });
+ }
+ }
+ }
+
+ public void setDismissAllInProgress(boolean dismissAllInProgress) {
+ mDismissAllInProgress = dismissAllInProgress;
+ }
+
/**
* A listener that is notified when some child locations might have changed.
*/
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollState.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollState.java
index f48739c708f9c..76115a7a75ad8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollState.java
@@ -21,6 +21,8 @@ import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
+import com.android.systemui.R;
+import com.android.systemui.statusbar.DismissView;
import com.android.systemui.statusbar.ExpandableView;
import com.android.systemui.statusbar.SpeedBumpView;
@@ -38,10 +40,13 @@ public class StackScrollState {
private final ViewGroup mHostView;
private Map mStateMap;
private final Rect mClipRect = new Rect();
+ private final int mClearAllTopPadding;
public StackScrollState(ViewGroup hostView) {
mHostView = hostView;
mStateMap = new HashMap();
+ mClearAllTopPadding = hostView.getContext().getResources().getDimensionPixelSize(
+ R.dimen.clear_all_padding_top);
}
public ViewGroup getHostView() {
@@ -90,6 +95,7 @@ public class StackScrollState {
if (!state.gone) {
float alpha = child.getAlpha();
float yTranslation = child.getTranslationY();
+ float xTranslation = child.getTranslationX();
float zTranslation = child.getTranslationZ();
float scale = child.getScaleX();
int height = child.getActualHeight();
@@ -99,7 +105,7 @@ public class StackScrollState {
float newScale = state.scale;
int newHeight = state.height;
boolean becomesInvisible = newAlpha == 0.0f;
- if (alpha != newAlpha) {
+ if (alpha != newAlpha && xTranslation == 0) {
// apply layer type
boolean becomesFullyVisible = newAlpha == 1.0f;
boolean newLayerTypeIsHardware = !becomesInvisible && !becomesFullyVisible;
@@ -167,6 +173,10 @@ public class StackScrollState {
if(child instanceof SpeedBumpView) {
float lineEnd = newYTranslation + newHeight / 2;
performSpeedBumpAnimation(i, (SpeedBumpView) child, lineEnd);
+ } else if (child instanceof DismissView) {
+ DismissView dismissView = (DismissView) child;
+ boolean visible = state.topOverLap < mClearAllTopPadding;
+ dismissView.performVisibilityAnimation(visible);
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java
index 0c8467569f3e6..71524ec464983 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java
@@ -159,7 +159,7 @@ public class StackStateAnimator {
}
// start alpha animation
- if (alphaChanging) {
+ if (alphaChanging && child.getTranslationX() == 0) {
startAlphaAnimation(child, viewState, delay);
}