From 7d5f374dda06edbd7931d3faaacb75feab48b005 Mon Sep 17 00:00:00 2001 From: Selim Cinek Date: Fri, 7 Nov 2014 18:07:49 +0100 Subject: [PATCH] Improved the dismiss all animation Added an AVD to the icon and changed the order to be from bottom to the top. Bug: 17903685 Bug: 17007783 Change-Id: Ia1509e2d4e02c87782285e05b7b7fb6a11854f95 --- .../anim/dismiss_all_shape_animation_1.xml | 22 +++ .../anim/dismiss_all_shape_animation_2.xml | 30 ++++ .../anim/dismiss_all_shape_animation_3.xml | 30 ++++ ...s_all_shape_animation_rectangle_path_1.xml | 31 ++++ ...all_shape_animation_rectangle_path_1_1.xml | 31 ++++ ...all_shape_animation_rectangle_path_1_2.xml | 31 ++++ .../res/drawable/dismiss_all_shape.xml | 39 +++++ .../drawable/dismiss_all_shape_animation.xml | 21 +++ .../SystemUI/res/drawable/ic_dismiss_all.xml | 31 ---- .../status_bar_notification_dismiss_all.xml | 8 +- .../systemui/statusbar/DismissView.java | 33 +++++ .../systemui/statusbar/DismissViewButton.java | 136 ++++++++++++++++++ .../statusbar/DismissViewImageButton.java | 69 --------- .../statusbar/phone/PhoneStatusBar.java | 6 +- .../stack/NotificationStackScrollLayout.java | 19 ++- 15 files changed, 427 insertions(+), 110 deletions(-) create mode 100644 packages/SystemUI/res/anim/dismiss_all_shape_animation_1.xml create mode 100644 packages/SystemUI/res/anim/dismiss_all_shape_animation_2.xml create mode 100644 packages/SystemUI/res/anim/dismiss_all_shape_animation_3.xml create mode 100644 packages/SystemUI/res/anim/dismiss_all_shape_animation_rectangle_path_1.xml create mode 100644 packages/SystemUI/res/anim/dismiss_all_shape_animation_rectangle_path_1_1.xml create mode 100644 packages/SystemUI/res/anim/dismiss_all_shape_animation_rectangle_path_1_2.xml create mode 100644 packages/SystemUI/res/drawable/dismiss_all_shape.xml create mode 100644 packages/SystemUI/res/drawable/dismiss_all_shape_animation.xml delete mode 100644 packages/SystemUI/res/drawable/ic_dismiss_all.xml create mode 100644 packages/SystemUI/src/com/android/systemui/statusbar/DismissViewButton.java delete mode 100644 packages/SystemUI/src/com/android/systemui/statusbar/DismissViewImageButton.java 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() {