From 1f62495a0aaf2d094c19bbdcf148d49360e052d4 Mon Sep 17 00:00:00 2001 From: Selim Cinek Date: Thu, 8 Jun 2017 19:11:50 -0700 Subject: [PATCH 1/2] Avoiding weird icon positions When expanding quickly we switch to a linear interpolation. In this case the last icon may be stuck in between the shelf position and the notification position, which looks pretty bad. We therefore optimize this case better to avoid these weird in-between cases. Test: manual, expand with various notifications Fixes: 63088105 Fixes: 62374617 Change-Id: I95f72c9defc6c941a5a6a71829d239529c3861e9 --- .../systemui/statusbar/NotificationShelf.java | 68 ++++++++++++++++--- .../phone/NotificationIconContainer.java | 7 ++ .../statusbar/stack/AmbientState.java | 9 +++ .../stack/NotificationStackScrollLayout.java | 3 +- 4 files changed, 78 insertions(+), 9 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java index 97e2f6d3e6f14..7abceaf41c70f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java @@ -16,15 +16,18 @@ package com.android.systemui.statusbar; +import static com.android.systemui.statusbar.phone.NotificationIconContainer.IconState.NO_VALUE; +import static com.android.systemui.statusbar.phone.NotificationIconContainer.OVERFLOW_EARLY_AMOUNT; + import android.content.Context; import android.content.res.Configuration; import android.content.res.Resources; import android.os.SystemProperties; import android.util.AttributeSet; -import android.util.Log; import android.view.View; import android.view.ViewGroup; import android.view.accessibility.AccessibilityNodeInfo; + import com.android.systemui.Interpolators; import com.android.systemui.R; import com.android.systemui.ViewInvertHelper; @@ -315,26 +318,65 @@ public class NotificationShelf extends ActivatableNotificationView implements private float updateIconAppearance(ExpandableNotificationRow row, float expandAmount, boolean scrolling, boolean scrollingFast, boolean expandingAnimated, boolean isLastChild) { + StatusBarIconView icon = row.getEntry().expandedIcon; + NotificationIconContainer.IconState iconState = getIconState(icon); + if (iconState == null) { + return 0.0f; + } + // Let calculate how much the view is in the shelf float viewStart = row.getTranslationY(); int fullHeight = row.getActualHeight() + mPaddingBetweenElements; float iconTransformDistance = getIntrinsicHeight() * 1.5f; iconTransformDistance *= NotificationUtils.interpolate(1.f, 1.5f, expandAmount); + iconTransformDistance = Math.min(iconTransformDistance, fullHeight); if (isLastChild) { fullHeight = Math.min(fullHeight, row.getMinHeight() - getIntrinsicHeight()); iconTransformDistance = Math.min(iconTransformDistance, row.getMinHeight() - getIntrinsicHeight()); } float viewEnd = viewStart + fullHeight; + if (expandingAnimated && mAmbientState.getScrollY() == 0 + && !mAmbientState.isOnKeyguard() && !iconState.isLastExpandIcon) { + // We are expanding animated. Because we switch to a linear interpolation in this case, + // the last icon may be stuck in between the shelf position and the notification + // position, which looks pretty bad. We therefore optimize this case by applying a + // shorter transition such that the icon is either fully in the notification or we clamp + // it into the shelf if it's close enough. + // We need to persist this, since after the expansion, the behavior should still be the + // same. + float position = mAmbientState.getIntrinsicPadding() + + mHostLayout.getPositionInLinearLayout(row); + int maxShelfStart = mMaxLayoutHeight - getIntrinsicHeight(); + if (position < maxShelfStart && position + row.getIntrinsicHeight() >= maxShelfStart + && row.getTranslationY() < position) { + iconState.isLastExpandIcon = true; + iconState.customTransformHeight = NO_VALUE; + // Let's check if we're close enough to snap into the shelf + boolean forceInShelf = mMaxLayoutHeight - getIntrinsicHeight() - position + < getIntrinsicHeight(); + if (!forceInShelf) { + // We are overlapping the shelf but not enough, so the icon needs to be + // repositioned + iconState.customTransformHeight = (int) (mMaxLayoutHeight + - getIntrinsicHeight() - position); + } + } + } float fullTransitionAmount; float iconTransitionAmount; float shelfStart = getTranslationY(); + if (iconState.hasCustomTransformHeight()) { + fullHeight = iconState.customTransformHeight; + iconTransformDistance = iconState.customTransformHeight; + } + boolean fullyInOrOut = true; if (viewEnd >= shelfStart && (!mAmbientState.isUnlockHintRunning() || row.isInShelf()) && (mAmbientState.isShadeExpanded() || (!row.isPinned() && !row.isHeadsUpAnimatingAway()))) { if (viewStart < shelfStart) { - float fullAmount = (shelfStart - viewStart) / fullHeight; + fullAmount = Math.min(1.0f, fullAmount); float interpolatedAmount = Interpolators.ACCELERATE_DECELERATE.getInterpolation( fullAmount); interpolatedAmount = NotificationUtils.interpolate( @@ -344,7 +386,7 @@ public class NotificationShelf extends ActivatableNotificationView implements iconTransitionAmount = (shelfStart - viewStart) / iconTransformDistance; iconTransitionAmount = Math.min(1.0f, iconTransitionAmount); iconTransitionAmount = 1.0f - iconTransitionAmount; - + fullyInOrOut = false; } else { fullTransitionAmount = 1.0f; iconTransitionAmount = 1.0f; @@ -353,6 +395,10 @@ public class NotificationShelf extends ActivatableNotificationView implements fullTransitionAmount = 0.0f; iconTransitionAmount = 0.0f; } + if (fullyInOrOut && !expandingAnimated && iconState.isLastExpandIcon) { + iconState.isLastExpandIcon = false; + iconState.customTransformHeight = NO_VALUE; + } updateIconPositioning(row, iconTransitionAmount, fullTransitionAmount, iconTransformDistance, scrolling, scrollingFast, expandingAnimated, isLastChild); return fullTransitionAmount; @@ -366,9 +412,10 @@ public class NotificationShelf extends ActivatableNotificationView implements if (iconState == null) { return; } + boolean forceInShelf = iconState.isLastExpandIcon && !iconState.hasCustomTransformHeight(); float clampedAmount = iconTransitionAmount > 0.5f ? 1.0f : 0.0f; if (clampedAmount == fullTransitionAmount) { - iconState.noAnimations = scrollingFast || expandingAnimated; + iconState.noAnimations = (scrollingFast || expandingAnimated) && !forceInShelf; iconState.useFullTransitionAmount = iconState.noAnimations || (!ICON_ANMATIONS_WHILE_SCROLLING && fullTransitionAmount == 0.0f && scrolling); iconState.useLinearTransitionAmount = !ICON_ANMATIONS_WHILE_SCROLLING @@ -376,12 +423,18 @@ public class NotificationShelf extends ActivatableNotificationView implements iconState.translateContent = mMaxLayoutHeight - getTranslationY() - getIntrinsicHeight() > 0; } - if (scrollingFast || (expandingAnimated && iconState.useFullTransitionAmount - && !ViewState.isAnimatingY(icon))) { + if (!forceInShelf && (scrollingFast || (expandingAnimated + && iconState.useFullTransitionAmount && !ViewState.isAnimatingY(icon)))) { iconState.cancelAnimations(icon); iconState.useFullTransitionAmount = true; iconState.noAnimations = true; } + if (iconState.hasCustomTransformHeight()) { + iconState.useFullTransitionAmount = true; + } + if (iconState.isLastExpandIcon) { + iconState.translateContent = false; + } float transitionAmount; if (isLastChild || !USE_ANIMATIONS_WHEN_OPENING || iconState.useFullTransitionAmount || iconState.useLinearTransitionAmount) { @@ -548,8 +601,7 @@ public class NotificationShelf extends ActivatableNotificationView implements if (!hasOverflow) { // we have to ensure that adding the low priority notification won't lead to an // overflow - collapsedPadding -= (1.0f + NotificationIconContainer.OVERFLOW_EARLY_AMOUNT) - * mCollapsedIcons.getIconSize(); + collapsedPadding -= (1.0f + OVERFLOW_EARLY_AMOUNT) * mCollapsedIcons.getIconSize(); } float padding = NotificationUtils.interpolate(collapsedPadding, mShelfIcons.getPaddingEnd(), diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java index 021e11acbcf56..6f5ad9614a266 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java @@ -526,6 +526,7 @@ public class NotificationIconContainer extends AlphaOptimizedFrameLayout { } public class IconState extends ViewState { + public static final int NO_VALUE = NotificationIconContainer.NO_VALUE; public float iconAppearAmount = 1.0f; public float clampedAppearAmount = 1.0f; public int visibleState; @@ -538,6 +539,8 @@ public class NotificationIconContainer extends AlphaOptimizedFrameLayout { public boolean justUndarkened; public int iconColor = StatusBarIconView.NO_COLOR; public boolean noAnimations; + public boolean isLastExpandIcon; + public int customTransformHeight = NO_VALUE; @Override public void applyToView(View view) { @@ -615,6 +618,10 @@ public class NotificationIconContainer extends AlphaOptimizedFrameLayout { justUndarkened = false; } + public boolean hasCustomTransformHeight() { + return isLastExpandIcon && customTransformHeight != NO_VALUE; + } + @Override public void initFrom(View view) { super.initFrom(view); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/AmbientState.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/AmbientState.java index b7b991e36710d..ba1e7c2d86c52 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/AmbientState.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/AmbientState.java @@ -62,6 +62,7 @@ public class AmbientState { private boolean mHasPulsingNotifications; private boolean mUnlockHintRunning; private boolean mQsCustomizerShowing; + private int mIntrinsicPadding; public AmbientState(Context context) { reload(context); @@ -323,4 +324,12 @@ public class AmbientState { public void setQsCustomizerShowing(boolean qsCustomizerShowing) { mQsCustomizerShowing = qsCustomizerShowing; } + + public void setIntrinsicPadding(int intrinsicPadding) { + mIntrinsicPadding = intrinsicPadding; + } + + public int getIntrinsicPadding() { + return mIntrinsicPadding; + } } 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 cbd315b940f3c..41cde9c7dd5e2 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java @@ -2735,7 +2735,7 @@ public class NotificationStackScrollLayout extends ViewGroup return view.getHeight(); } - private int getPositionInLinearLayout(View requestedView) { + public int getPositionInLinearLayout(View requestedView) { ExpandableNotificationRow childInGroup = null; ExpandableNotificationRow requestedRow = null; if (isChildInGroup(requestedView)) { @@ -3650,6 +3650,7 @@ public class NotificationStackScrollLayout extends ViewGroup public void setIntrinsicPadding(int intrinsicPadding) { mIntrinsicPadding = intrinsicPadding; + mAmbientState.setIntrinsicPadding(intrinsicPadding); } public int getIntrinsicPadding() { From 460f9fe4cb3ffa3b59946f1a93e458ea5364263d Mon Sep 17 00:00:00 2001 From: Selim Cinek Date: Wed, 28 Jun 2017 14:17:22 +0200 Subject: [PATCH 2/2] Fixed the accessibility of the reply button The new button didn't have a content description before and could therefore not be read. Change-Id: I66f2c52b50494f7347d5beebc44c7d4fecfd33b2 Fixes: 62639422 Test: manual add reply notification, observe talkback --- core/res/res/layout/notification_template_right_icon.xml | 6 ++++-- core/res/res/values/strings.xml | 3 +++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/core/res/res/layout/notification_template_right_icon.xml b/core/res/res/layout/notification_template_right_icon.xml index aa4e05b15d192..fbf75387b786d 100644 --- a/core/res/res/layout/notification_template_right_icon.xml +++ b/core/res/res/layout/notification_template_right_icon.xml @@ -26,8 +26,9 @@ android:layout_gravity="top|end" android:layout_marginTop="36dp" android:layout_marginEnd="@dimen/notification_content_margin_end" - android:scaleType="centerCrop"/> - + diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml index e6c95c069d859..5a98a1e824062 100644 --- a/core/res/res/values/strings.xml +++ b/core/res/res/values/strings.xml @@ -4713,6 +4713,9 @@ Emergency messages test + + Reply +