diff --git a/packages/SystemUI/res/anim/dismiss_all_shape_animation_1.xml b/packages/SystemUI/res/anim/dismiss_all_shape_animation_1.xml
new file mode 100644
index 0000000000000..3cc98d8f7ed95
--- /dev/null
+++ b/packages/SystemUI/res/anim/dismiss_all_shape_animation_1.xml
@@ -0,0 +1,22 @@
+
+
+
+
diff --git a/packages/SystemUI/res/anim/dismiss_all_shape_animation_2.xml b/packages/SystemUI/res/anim/dismiss_all_shape_animation_2.xml
new file mode 100644
index 0000000000000..eda843d03ba29
--- /dev/null
+++ b/packages/SystemUI/res/anim/dismiss_all_shape_animation_2.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
diff --git a/packages/SystemUI/res/anim/dismiss_all_shape_animation_3.xml b/packages/SystemUI/res/anim/dismiss_all_shape_animation_3.xml
new file mode 100644
index 0000000000000..cab3d5cc2367c
--- /dev/null
+++ b/packages/SystemUI/res/anim/dismiss_all_shape_animation_3.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
diff --git a/packages/SystemUI/res/anim/dismiss_all_shape_animation_rectangle_path_1.xml b/packages/SystemUI/res/anim/dismiss_all_shape_animation_rectangle_path_1.xml
new file mode 100644
index 0000000000000..e435d9a9a69e5
--- /dev/null
+++ b/packages/SystemUI/res/anim/dismiss_all_shape_animation_rectangle_path_1.xml
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
diff --git a/packages/SystemUI/res/anim/dismiss_all_shape_animation_rectangle_path_1_1.xml b/packages/SystemUI/res/anim/dismiss_all_shape_animation_rectangle_path_1_1.xml
new file mode 100644
index 0000000000000..e31a7dbcebc55
--- /dev/null
+++ b/packages/SystemUI/res/anim/dismiss_all_shape_animation_rectangle_path_1_1.xml
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
diff --git a/packages/SystemUI/res/anim/dismiss_all_shape_animation_rectangle_path_1_2.xml b/packages/SystemUI/res/anim/dismiss_all_shape_animation_rectangle_path_1_2.xml
new file mode 100644
index 0000000000000..2409612cb250b
--- /dev/null
+++ b/packages/SystemUI/res/anim/dismiss_all_shape_animation_rectangle_path_1_2.xml
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
diff --git a/packages/SystemUI/res/drawable/dismiss_all_shape.xml b/packages/SystemUI/res/drawable/dismiss_all_shape.xml
new file mode 100644
index 0000000000000..fb371c6beb07e
--- /dev/null
+++ b/packages/SystemUI/res/drawable/dismiss_all_shape.xml
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/packages/SystemUI/res/drawable/dismiss_all_shape_animation.xml b/packages/SystemUI/res/drawable/dismiss_all_shape_animation.xml
new file mode 100644
index 0000000000000..9e71cbeebea49
--- /dev/null
+++ b/packages/SystemUI/res/drawable/dismiss_all_shape_animation.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
diff --git a/packages/SystemUI/res/drawable/ic_dismiss_all.xml b/packages/SystemUI/res/drawable/ic_dismiss_all.xml
deleted file mode 100644
index c32e5b1138fd1..0000000000000
--- a/packages/SystemUI/res/drawable/ic_dismiss_all.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-
-
-
-
-
-
diff --git a/packages/SystemUI/res/layout/status_bar_notification_dismiss_all.xml b/packages/SystemUI/res/layout/status_bar_notification_dismiss_all.xml
index 9e0f82cb2f756..6a000fd660223 100644
--- a/packages/SystemUI/res/layout/status_bar_notification_dismiss_all.xml
+++ b/packages/SystemUI/res/layout/status_bar_notification_dismiss_all.xml
@@ -20,13 +20,13 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="gone"
- >
-
+
+ android:contentDescription="@string/accessibility_clear_all"/>
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/DismissView.java b/packages/SystemUI/src/com/android/systemui/statusbar/DismissView.java
index 479c2fb8e2aa7..d9276bf8592bc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/DismissView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/DismissView.java
@@ -17,12 +17,15 @@
package com.android.systemui.statusbar;
import android.content.Context;
+import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.View;
import com.android.systemui.R;
public class DismissView extends StackScrollerDecorView {
+ private boolean mDismissAllInProgress;
+ private DismissViewButton mDismissButton;
public DismissView(Context context, AttributeSet attrs) {
super(context, attrs);
@@ -33,6 +36,12 @@ public class DismissView extends StackScrollerDecorView {
return findViewById(R.id.dismiss_text);
}
+ @Override
+ protected void onFinishInflate() {
+ super.onFinishInflate();
+ mDismissButton = (DismissViewButton) findContentView();
+ }
+
public void setOnButtonClickListener(OnClickListener listener) {
mContent.setOnClickListener(listener);
}
@@ -43,4 +52,28 @@ public class DismissView extends StackScrollerDecorView {
|| touchY < mContent.getY()
|| touchY > mContent.getY() + mContent.getHeight();
}
+
+ public void showClearButton() {
+ mDismissButton.showButton();
+ }
+
+ public void setDismissAllInProgress(boolean dismissAllInProgress) {
+ if (dismissAllInProgress) {
+ setClipBounds(null);
+ }
+ mDismissAllInProgress = dismissAllInProgress;
+ }
+
+ @Override
+ public void setClipBounds(Rect clipBounds) {
+ if (mDismissAllInProgress) {
+ // we don't want any clipping to happen!
+ return;
+ }
+ super.setClipBounds(clipBounds);
+ }
+
+ public boolean isButtonVisible() {
+ return mDismissButton.isButtonStatic();
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/DismissViewButton.java b/packages/SystemUI/src/com/android/systemui/statusbar/DismissViewButton.java
new file mode 100644
index 0000000000000..f2a5673ef1aed
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/DismissViewButton.java
@@ -0,0 +1,136 @@
+/*
+ * 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.graphics.Canvas;
+import android.graphics.Rect;
+import android.graphics.drawable.AnimatedVectorDrawable;
+import android.graphics.drawable.Drawable;
+import android.os.SystemClock;
+import android.util.AttributeSet;
+import android.view.Choreographer;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.ViewRootImpl;
+import android.widget.Button;
+import com.android.systemui.R;
+import com.android.systemui.statusbar.stack.NotificationStackScrollLayout;
+
+public class DismissViewButton extends Button {
+ private AnimatedVectorDrawable mAnimatedDismissDrawable;
+ private final Drawable mStaticDismissDrawable;
+ private Drawable mActiveDrawable;
+
+ public DismissViewButton(Context context) {
+ this(context, null);
+ }
+
+ public DismissViewButton(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public DismissViewButton(Context context, AttributeSet attrs, int defStyleAttr) {
+ this(context, attrs, defStyleAttr, 0);
+ }
+
+ public DismissViewButton(Context context, AttributeSet attrs, int defStyleAttr,
+ int defStyleRes) {
+ super(context, attrs, defStyleAttr, defStyleRes);
+ mAnimatedDismissDrawable = (AnimatedVectorDrawable) getContext().getResources().getDrawable(
+ R.drawable.dismiss_all_shape_animation).mutate();
+ mAnimatedDismissDrawable.setCallback(this);
+ mAnimatedDismissDrawable.setBounds(0,
+ 0,
+ mAnimatedDismissDrawable.getIntrinsicWidth(),
+ mAnimatedDismissDrawable.getIntrinsicHeight());
+ mStaticDismissDrawable = getContext().getResources().getDrawable(
+ R.drawable.dismiss_all_shape);
+ mStaticDismissDrawable.setBounds(0,
+ 0,
+ mStaticDismissDrawable.getIntrinsicWidth(),
+ mStaticDismissDrawable.getIntrinsicHeight());
+ mStaticDismissDrawable.setCallback(this);
+ mActiveDrawable = mStaticDismissDrawable;
+ }
+
+ @Override
+ protected void onDraw(Canvas canvas) {
+ super.onDraw(canvas);
+ canvas.save();
+ int drawableHeight = mActiveDrawable.getBounds().height();
+ boolean isRtl = (getLayoutDirection() == View.LAYOUT_DIRECTION_RTL);
+ int dx = isRtl ? getWidth() / 2 + drawableHeight / 2 : getWidth() / 2 - drawableHeight / 2;
+ canvas.translate(dx, getHeight() / 2.0f + drawableHeight /
+ 2.0f);
+ canvas.scale(isRtl ? -1.0f : 1.0f, -1.0f);
+ mActiveDrawable.draw(canvas);
+ canvas.restore();
+ }
+
+ @Override
+ public boolean performClick() {
+ if (!mAnimatedDismissDrawable.isRunning()) {
+ mActiveDrawable = mAnimatedDismissDrawable;
+ mAnimatedDismissDrawable.start();
+ }
+ return super.performClick();
+ }
+
+ @Override
+ protected boolean verifyDrawable(Drawable who) {
+ return super.verifyDrawable(who)
+ || who == mAnimatedDismissDrawable
+ || who == mStaticDismissDrawable;
+ }
+
+ @Override
+ public boolean hasOverlappingRendering() {
+ return false;
+ }
+
+ /**
+ * This method returns the drawing rect for the view which is different from the regular
+ * drawing rect, since we layout all children in the {@link NotificationStackScrollLayout} at
+ * position 0 and usually the translation is neglected. The standard implementation doesn't
+ * account for translation.
+ *
+ * @param outRect The (scrolled) drawing bounds of the view.
+ */
+ @Override
+ public void getDrawingRect(Rect outRect) {
+ super.getDrawingRect(outRect);
+ float translationX = ((ViewGroup) mParent).getTranslationX();
+ float translationY = ((ViewGroup) mParent).getTranslationY();
+ outRect.left += translationX;
+ outRect.right += translationX;
+ outRect.top += translationY;
+ outRect.bottom += translationY;
+ }
+
+ public void showButton() {
+ mActiveDrawable = mStaticDismissDrawable;
+ invalidate();
+ }
+
+ /**
+ * @return Whether the button is currently static and not being animated.
+ */
+ public boolean isButtonStatic() {
+ return mActiveDrawable == mStaticDismissDrawable;
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/DismissViewImageButton.java b/packages/SystemUI/src/com/android/systemui/statusbar/DismissViewImageButton.java
deleted file mode 100644
index 35fd688319ad8..0000000000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/DismissViewImageButton.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * 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.graphics.Rect;
-import android.util.AttributeSet;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ImageButton;
-import com.android.systemui.R;
-import com.android.systemui.statusbar.stack.NotificationStackScrollLayout;
-
-public class DismissViewImageButton extends ImageButton {
- public DismissViewImageButton(Context context) {
- super(context);
- }
-
- public DismissViewImageButton(Context context, AttributeSet attrs) {
- super(context, attrs);
- }
-
- public DismissViewImageButton(Context context, AttributeSet attrs, int defStyleAttr) {
- super(context, attrs, defStyleAttr);
- }
-
- public DismissViewImageButton(Context context, AttributeSet attrs, int defStyleAttr,
- int defStyleRes) {
- super(context, attrs, defStyleAttr, defStyleRes);
- }
-
- /**
- * This method returns the drawing rect for the view which is different from the regular
- * drawing rect, since we layout all children in the {@link NotificationStackScrollLayout} at
- * position 0 and usually the translation is neglected. The standard implementation doesn't
- * account for translation.
- *
- * @param outRect The (scrolled) drawing bounds of the view.
- */
- @Override
- public void getDrawingRect(Rect outRect) {
- super.getDrawingRect(outRect);
- float translationX = ((ViewGroup) mParent).getTranslationX();
- float translationY = ((ViewGroup) mParent).getTranslationY();
- outRect.left += translationX;
- outRect.right += translationX;
- outRect.top += translationY;
- outRect.bottom += translationY;
- }
-
- @Override
- public boolean hasOverlappingRendering() {
- return false;
- }
-}
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 ce2ce6b62b723..004212b8817f3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -966,12 +966,12 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
// accelerating the swipes
int rowDelayDecrement = 10;
int currentDelay = 140;
- int totalDelay = 0;
+ int totalDelay = 180;
int numItems = hideAnimatedList.size();
- for (int i = 0; i < numItems; i++) {
+ for (int i = numItems - 1; i >= 0; i--) {
View view = hideAnimatedList.get(i);
Runnable endRunnable = null;
- if (i == numItems - 1) {
+ if (i == 0) {
endRunnable = animationFinishAction;
}
mStackScroller.dismissViewAnimated(view, endRunnable, totalDelay, 260);
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 d543cff178058..ab25c45190dc1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
@@ -1604,6 +1604,12 @@ public class NotificationStackScrollLayout extends ViewGroup
((ExpandableView) child).setOnHeightChangedListener(this);
generateAddAnimation(child, false /* fromMoreCard */);
updateAnimationState(child);
+ if (canChildBeDismissed(child)) {
+ // Make sure the dismissButton is visible and not in the animated state.
+ // We need to do this to avoid a race where a clearable notification is added after the
+ // dismiss animation is finished
+ mDismissView.showClearButton();
+ }
}
public void setAnimationsEnabled(boolean animationsEnabled) {
@@ -2234,8 +2240,7 @@ public class NotificationStackScrollLayout extends ViewGroup
updateContentHeight();
notifyHeightChangeListener(mDismissView);
} else {
- mDismissView.setWillBeGone(true);
- mDismissView.performVisibilityAnimation(false, new Runnable() {
+ Runnable dimissHideFinishRunnable = new Runnable() {
@Override
public void run() {
mDismissView.setVisibility(GONE);
@@ -2243,13 +2248,21 @@ public class NotificationStackScrollLayout extends ViewGroup
updateContentHeight();
notifyHeightChangeListener(mDismissView);
}
- });
+ };
+ if (mDismissView.isButtonVisible() && mIsExpanded) {
+ mDismissView.setWillBeGone(true);
+ mDismissView.performVisibilityAnimation(false, dimissHideFinishRunnable);
+ } else {
+ dimissHideFinishRunnable.run();
+ mDismissView.showClearButton();
+ }
}
}
}
public void setDismissAllInProgress(boolean dismissAllInProgress) {
mDismissAllInProgress = dismissAllInProgress;
+ mDismissView.setDismissAllInProgress(dismissAllInProgress);
}
public boolean isDismissViewNotGone() {