From 6eaacf25aabfac6018404610ce2f3df759558d3b Mon Sep 17 00:00:00 2001 From: Selim Cinek Date: Thu, 7 Sep 2017 18:53:17 -0700 Subject: [PATCH] Fixed the icon clipping of the notification shelf Before the icon wasn't clipped to it's notification container and could go out of bounds. We're now clipping it to it's surrounding notification. Change-Id: I1b9a3650eb3e3f0bcd7d7cef087afb7cc41ccf62 Fixes: 63477094 Test: add notifications, observe icon animations, better clipping --- packages/SystemUI/res/values/ids.xml | 1 + .../systemui/statusbar/NotificationShelf.java | 50 +++++++++++++++++++ 2 files changed, 51 insertions(+) diff --git a/packages/SystemUI/res/values/ids.xml b/packages/SystemUI/res/values/ids.xml index b27deddb4dd0a..2148c80474763 100644 --- a/packages/SystemUI/res/values/ids.xml +++ b/packages/SystemUI/res/values/ids.xml @@ -59,6 +59,7 @@ + diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java index 5eefe9ae07369..184b95d562606 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java @@ -22,10 +22,12 @@ import static com.android.systemui.statusbar.phone.NotificationIconContainer.OVE import android.content.Context; import android.content.res.Configuration; import android.content.res.Resources; +import android.graphics.Rect; import android.os.SystemProperties; import android.util.AttributeSet; import android.view.View; import android.view.ViewGroup; +import android.view.ViewTreeObserver; import android.view.accessibility.AccessibilityNodeInfo; import com.android.systemui.Interpolators; @@ -53,6 +55,7 @@ public class NotificationShelf extends ActivatableNotificationView implements SystemProperties.getBoolean("debug.icon_opening_animations", true); private static final boolean ICON_ANMATIONS_WHILE_SCROLLING = SystemProperties.getBoolean("debug.icon_scroll_animations", true); + private static final int TAG_CONTINUOUS_CLIPPING = R.id.continuous_clipping_tag; private ViewInvertHelper mViewInvertHelper; private boolean mDark; private NotificationIconContainer mShelfIcons; @@ -305,6 +308,16 @@ public class NotificationShelf extends ActivatableNotificationView implements mShelfIcons.setSpeedBumpIndex(mAmbientState.getSpeedBumpIndex()); mShelfIcons.calculateIconTranslations(); mShelfIcons.applyIconStates(); + for (int i = 0; i < mHostLayout.getChildCount(); i++) { + View child = mHostLayout.getChildAt(i); + if (!(child instanceof ExpandableNotificationRow) + || child.getVisibility() == GONE) { + continue; + } + ExpandableNotificationRow row = (ExpandableNotificationRow) child; + updateIconClipAmount(row); + updateContinuousClipping(row); + } boolean hideBackground = numViewsInShelf < 1.0f; setHideBackground(hideBackground || backgroundForceHidden); if (mNotGoneIndex == -1) { @@ -312,6 +325,43 @@ public class NotificationShelf extends ActivatableNotificationView implements } } + private void updateIconClipAmount(ExpandableNotificationRow row) { + float maxTop = row.getTranslationY(); + StatusBarIconView icon = row.getEntry().expandedIcon; + float shelfIconPosition = getTranslationY() + icon.getTop() + icon.getTranslationY(); + if (shelfIconPosition < maxTop) { + int top = (int) (maxTop - shelfIconPosition); + Rect clipRect = new Rect(0, top, icon.getWidth(), Math.max(top, icon.getHeight())); + icon.setClipBounds(clipRect); + } else { + icon.setClipBounds(null); + } + } + + private void updateContinuousClipping(final ExpandableNotificationRow row) { + StatusBarIconView icon = row.getEntry().expandedIcon; + boolean needsContinuousClipping = ViewState.isAnimatingY(icon); + boolean isContinuousClipping = icon.getTag(TAG_CONTINUOUS_CLIPPING) != null; + if (needsContinuousClipping && !isContinuousClipping) { + ViewTreeObserver.OnPreDrawListener predrawListener = + new ViewTreeObserver.OnPreDrawListener() { + @Override + public boolean onPreDraw() { + boolean animatingY = ViewState.isAnimatingY(icon); + if (!animatingY || !icon.isAttachedToWindow()) { + icon.getViewTreeObserver().removeOnPreDrawListener(this); + icon.setTag(TAG_CONTINUOUS_CLIPPING, null); + return true; + } + updateIconClipAmount(row); + return true; + } + }; + icon.getViewTreeObserver().addOnPreDrawListener(predrawListener); + icon.setTag(TAG_CONTINUOUS_CLIPPING, predrawListener); + } + } + private void updateNotificationClipHeight(ExpandableNotificationRow row, float notificationClipEnd) { float viewEnd = row.getTranslationY() + row.getActualHeight();