Improved the low priority behavior with the shelf

Low priority notification now don't just disappear,
but transform into an overflow such that there's still
some object permanence.

Test: add low-priority notifications, see dot transformation
Bug: 32437839
Change-Id: I90c03c7d88c01c199062bd5f7f0151629654a3a1
This commit is contained in:
Selim Cinek
2016-12-02 18:19:11 -08:00
parent 65d418ec89
commit 17e1b69523
4 changed files with 69 additions and 32 deletions

View File

@@ -891,7 +891,9 @@ public class ExpandableNotificationRow extends ActivatableNotificationView {
}
private void updateIconVisibilities() {
boolean visible = isChildInGroup() || isBelowSpeedBump() || mIconsVisible;
boolean visible = isChildInGroup()
|| (isBelowSpeedBump() && !NotificationShelf.SHOW_AMBIENT_ICONS)
|| mIconsVisible;
mPublicLayout.setIconsVisible(visible);
mPrivateLayout.setIconsVisible(visible);
if (mChildrenContainer != null) {

View File

@@ -43,6 +43,7 @@ import com.android.systemui.statusbar.stack.StackScrollState;
*/
public class NotificationShelf extends ActivatableNotificationView {
public static final boolean SHOW_AMBIENT_ICONS = true;
private static final boolean USE_ANIMATIONS_WHEN_OPENING =
SystemProperties.getBoolean("debug.icon_opening_animations", true);
private ViewInvertHelper mViewInvertHelper;
@@ -248,6 +249,7 @@ public class NotificationShelf extends ActivatableNotificationView {
notGoneIndex++;
previousColor = ownColorUntinted;
}
mShelfIcons.setSpeedBumpIndex(mAmbientState.getSpeedBumpIndex());
mShelfIcons.calculateIconTranslations();
mShelfIcons.applyIconStates();
boolean hideBackground = numViewsInShelf < 1.0f;
@@ -476,6 +478,7 @@ public class NotificationShelf extends ActivatableNotificationView {
float paddingStart = NotificationUtils.interpolate(start,
mShelfIcons.getPaddingStart(), openedAmount);
mShelfIcons.setActualPaddingStart(paddingStart);
mShelfIcons.setOpenedAmount(openedAmount);
}
public void setMaxLayoutHeight(int maxLayoutHeight) {

View File

@@ -127,9 +127,9 @@ public class NotificationIconAreaController {
return mPhoneStatusBar.getStatusBarHeight();
}
protected boolean shouldShowNotification(NotificationData.Entry entry,
NotificationData notificationData) {
if (notificationData.isAmbient(entry.key)
protected boolean shouldShowNotificationIcon(NotificationData.Entry entry,
NotificationData notificationData, boolean showAmbient) {
if (notificationData.isAmbient(entry.key) && !showAmbient
&& !NotificationData.showNotificationEvenIfUnprovisioned(entry.notification)) {
return false;
}
@@ -148,8 +148,10 @@ public class NotificationIconAreaController {
*/
public void updateNotificationIcons(NotificationData notificationData) {
updateIconsForLayout(notificationData, entry -> entry.icon, mNotificationIcons);
updateIconsForLayout(notificationData, entry -> entry.expandedIcon, mShelfIcons);
updateIconsForLayout(notificationData, entry -> entry.icon, mNotificationIcons,
false /* showAmbient */);
updateIconsForLayout(notificationData, entry -> entry.expandedIcon, mShelfIcons,
NotificationShelf.SHOW_AMBIENT_ICONS);
applyNotificationIconsTint();
ArrayList<NotificationData.Entry> activeNotifications
@@ -173,10 +175,11 @@ public class NotificationIconAreaController {
* @param notificationData the notification data to look up which notifications are relevant
* @param function A function to look up an icon view based on an entry
* @param hostLayout which layout should be updated
* @param showAmbient should ambient notification icons be shown
*/
private void updateIconsForLayout(NotificationData notificationData,
Function<NotificationData.Entry, StatusBarIconView> function,
NotificationIconContainer hostLayout) {
NotificationIconContainer hostLayout, boolean showAmbient) {
ArrayList<StatusBarIconView> toShow = new ArrayList<>(
mNotificationScrollLayout.getChildCount());
@@ -185,7 +188,7 @@ public class NotificationIconAreaController {
View view = mNotificationScrollLayout.getChildAt(i);
if (view instanceof ExpandableNotificationRow) {
NotificationData.Entry ent = ((ExpandableNotificationRow) view).getEntry();
if (shouldShowNotification(ent, notificationData)) {
if (shouldShowNotificationIcon(ent, notificationData, showAmbient)) {
toShow.add(function.apply(ent));
}
}

View File

@@ -89,6 +89,9 @@ public class NotificationIconContainer extends AlphaOptimizedFrameLayout {
private boolean mChangingViewPositions;
private int mAddAnimationStartIndex = -1;
private int mCannedAnimationStartIndex = -1;
private int mSpeedBumpIndex = -1;
private int mIconSize;
private float mOpenedAmount = 0.0f;
public NotificationIconContainer(Context context, AttributeSet attrs) {
super(context, attrs);
@@ -119,6 +122,7 @@ public class NotificationIconContainer extends AlphaOptimizedFrameLayout {
protected void onLayout(boolean changed, int l, int t, int r, int b) {
float centerY = getHeight() / 2.0f;
// we layout all our children on the left at the top
mIconSize = 0;
for (int i = 0; i < getChildCount(); i++) {
View child = getChildAt(i);
// We need to layout all children even the GONE ones, such that the heights are
@@ -127,6 +131,9 @@ public class NotificationIconContainer extends AlphaOptimizedFrameLayout {
int height = child.getMeasuredHeight();
int top = (int) (centerY - height / 2.0f);
child.layout(0, top, width, top + height);
if (i == 0) {
mIconSize = child.getWidth();
}
}
if (mShowAllIcons) {
resetViewStates();
@@ -216,42 +223,56 @@ public class NotificationIconContainer extends AlphaOptimizedFrameLayout {
*/
public void calculateIconTranslations() {
float translationX = getActualPaddingStart();
int overflowingIconIndex = -1;
int lastTwoIconWidth = 0;
int firstOverflowIndex = -1;
int childCount = getChildCount();
float layoutEnd = getLayoutEnd();
float overflowStart = layoutEnd - mIconSize * 2.2f;
boolean hasAmbient = mSpeedBumpIndex != -1 && mSpeedBumpIndex < getChildCount();
float visualOverflowStart = 0;
for (int i = 0; i < childCount; i++) {
View view = getChildAt(i);
IconState iconState = mIconStates.get(view);
iconState.xTranslation = translationX;
iconState.visibleState = StatusBarIconView.STATE_ICON;
translationX += iconState.iconAppearAmount * view.getWidth();
if (translationX > getLayoutEnd()) {
// we are overflowing it with this icon
overflowingIconIndex = i - 1;
lastTwoIconWidth = view.getWidth();
break;
boolean isAmbient = mSpeedBumpIndex != -1 && i >= mSpeedBumpIndex
&& iconState.iconAppearAmount > 0.0f;
boolean noOverflowAfter = i == childCount - 1;
if (mOpenedAmount != 0.0f) {
noOverflowAfter = noOverflowAfter && !hasAmbient;
}
iconState.visibleState = StatusBarIconView.STATE_ICON;
if (firstOverflowIndex == -1 && (isAmbient
|| (translationX >= (noOverflowAfter ? layoutEnd - mIconSize : overflowStart)))) {
firstOverflowIndex = noOverflowAfter ? i - 1 : i;
int totalDotLength = mStaticDotRadius * 6 + 2 * mDotPadding;
visualOverflowStart = overflowStart + mIconSize * 1.2f - totalDotLength / 2
- mIconSize * 0.5f + mStaticDotRadius;
if (isAmbient) {
visualOverflowStart = Math.min(translationX, visualOverflowStart
+ mStaticDotRadius * 2 + mDotPadding);
} else {
visualOverflowStart += (translationX - overflowStart) / mIconSize
* (mStaticDotRadius * 2 + mDotPadding);
}
}
translationX += iconState.iconAppearAmount * view.getWidth();
}
if (overflowingIconIndex != -1) {
if (firstOverflowIndex != -1) {
int numDots = 1;
View overflowIcon = getChildAt(overflowingIconIndex);
IconState overflowState = mIconStates.get(overflowIcon);
lastTwoIconWidth += overflowIcon.getWidth();
int dotWidth = mStaticDotRadius * 2 + mDotPadding;
int totalDotLength = mStaticDotRadius * 6 + 2 * mDotPadding;
translationX = (getLayoutEnd() - lastTwoIconWidth / 2 - totalDotLength / 2)
- overflowIcon.getWidth() * 0.3f + mStaticDotRadius;
float overflowStart = getLayoutEnd() - lastTwoIconWidth;
float overlapAmount = (overflowState.xTranslation - overflowStart)
/ overflowIcon.getWidth();
translationX += overlapAmount * dotWidth;
for (int i = overflowingIconIndex; i < childCount; i++) {
translationX = visualOverflowStart;
for (int i = firstOverflowIndex; i < childCount; i++) {
View view = getChildAt(i);
IconState iconState = mIconStates.get(view);
int dotWidth = mStaticDotRadius * 2 + mDotPadding;
iconState.xTranslation = translationX;
if (numDots <= 3) {
iconState.visibleState = StatusBarIconView.STATE_DOT;
translationX += numDots == 3 ? 3 * dotWidth : dotWidth;
if (numDots == 1 && iconState.iconAppearAmount < 0.8f) {
iconState.visibleState = StatusBarIconView.STATE_ICON;
numDots--;
} else {
iconState.visibleState = StatusBarIconView.STATE_DOT;
}
translationX += (numDots == 3 ? 3 * dotWidth : dotWidth)
* iconState.iconAppearAmount;
} else {
iconState.visibleState = StatusBarIconView.STATE_HIDDEN;
}
@@ -331,6 +352,14 @@ public class NotificationIconContainer extends AlphaOptimizedFrameLayout {
return mIconStates.get(icon);
}
public void setSpeedBumpIndex(int speedBumpIndex) {
mSpeedBumpIndex = speedBumpIndex;
}
public void setOpenedAmount(float expandAmount) {
mOpenedAmount = expandAmount;
}
public class IconState extends ViewState {
public float iconAppearAmount = 1.0f;
public float clampedAppearAmount = 1.0f;