Loading packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java +39 −199 Original line number Diff line number Diff line Loading @@ -16,9 +16,6 @@ package com.android.systemui.statusbar; import static com.android.systemui.Interpolators.FAST_OUT_SLOW_IN_REVERSE; import static com.android.systemui.statusbar.phone.NotificationIconContainer.IconState.NO_VALUE; import android.content.Context; import android.content.res.Configuration; import android.content.res.Resources; Loading @@ -34,7 +31,6 @@ import android.view.WindowInsets; import android.view.accessibility.AccessibilityNodeInfo; import com.android.internal.annotations.VisibleForTesting; import com.android.systemui.Interpolators; import com.android.systemui.R; import com.android.systemui.plugins.statusbar.StatusBarStateController.StateListener; import com.android.systemui.statusbar.notification.NotificationUtils; Loading @@ -55,8 +51,6 @@ import com.android.systemui.statusbar.phone.NotificationIconContainer; public class NotificationShelf extends ActivatableNotificationView implements View.OnLayoutChangeListener, StateListener { private static final boolean USE_ANIMATIONS_WHEN_OPENING = 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; Loading Loading @@ -174,18 +168,9 @@ public class NotificationShelf extends ActivatableNotificationView implements float viewEnd = lastViewState.yTranslation + lastViewState.height; viewState.copyFrom(lastViewState); viewState.height = getIntrinsicHeight(); viewState.yTranslation = Math.max(Math.min(viewEnd, maxShelfEnd) - viewState.height, getFullyClosedTranslation()); viewState.zTranslation = ambientState.getBaseZHeight(); // For the small display size, it's not enough to make the icon not covered by // the top cutout so the denominator add the height of cutout. // Totally, (getIntrinsicHeight() * 2 + mCutoutHeight) should be smaller then // mAmbientState.getTopPadding(). float openedAmount = (viewState.yTranslation - getFullyClosedTranslation()) / (getIntrinsicHeight() * 2 + mCutoutHeight); openedAmount = Math.min(1.0f, openedAmount); viewState.openedAmount = openedAmount; viewState.clipTopAmount = 0; viewState.alpha = 1; viewState.belowSpeedBump = mHostLayoutController.getSpeedBumpIndex() == 0; Loading Loading @@ -220,11 +205,6 @@ public class NotificationShelf extends ActivatableNotificationView implements View lastChild = mAmbientState.getLastVisibleBackgroundChild(); mNotGoneIndex = -1; float interpolationStart = mMaxLayoutHeight - getIntrinsicHeight() * 2; float expandAmount = 0.0f; if (shelfStart >= interpolationStart) { expandAmount = (shelfStart - interpolationStart) / getIntrinsicHeight(); expandAmount = Math.min(1.0f, expandAmount); } // find the first view that doesn't overlap with the shelf int notGoneIndex = 0; int colorOfViewBeforeLast = NO_COLOR; Loading @@ -239,7 +219,6 @@ public class NotificationShelf extends ActivatableNotificationView implements boolean scrollingFast = currentScrollVelocity > mScrollFastThreshold || (mAmbientState.isExpansionChanging() && Math.abs(mAmbientState.getExpandingVelocity()) > mScrollFastThreshold); boolean scrolling = currentScrollVelocity > 0; boolean expandingAnimated = mAmbientState.isExpansionChanging() && !mAmbientState.isPanelTracking(); int baseZHeight = mAmbientState.getBaseZHeight(); Loading @@ -249,8 +228,7 @@ public class NotificationShelf extends ActivatableNotificationView implements ActivatableNotificationView previousAnv = null; for (int i = 0; i < mHostLayoutController.getChildCount(); i++) { ExpandableView child = (ExpandableView) mHostLayoutController.getChildAt(i); ExpandableView child = mHostLayoutController.getChildAt(i); if (!child.needsClippingToShelf() || child.getVisibility() == GONE) { continue; } Loading @@ -268,9 +246,8 @@ public class NotificationShelf extends ActivatableNotificationView implements int clipTop = updateNotificationClipHeight(child, notificationClipEnd, notGoneIndex); clipTopAmount = Math.max(clipTop, clipTopAmount); float inShelfAmount = updateShelfTransformation(child, expandAmount, scrolling, scrollingFast, expandingAnimated, isLastChild); final float inShelfAmount = updateShelfTransformation(child, scrollingFast, expandingAnimated, isLastChild); // If the current row is an ExpandableNotificationRow, update its color, roundedness, // and icon state. if (child instanceof ExpandableNotificationRow) { Loading Loading @@ -498,56 +475,40 @@ public class NotificationShelf extends ActivatableNotificationView implements /** * @return the amount how much this notification is in the shelf */ private float updateShelfTransformation(ExpandableView view, float expandAmount, boolean scrolling, boolean scrollingFast, boolean expandingAnimated, boolean isLastChild) { StatusBarIconView icon = view.getShelfIcon(); NotificationIconContainer.IconState iconState = getIconState(icon); private float updateShelfTransformation(ExpandableView view, boolean scrollingFast, boolean expandingAnimated, boolean isLastChild) { // Let calculate how much the view is in the shelf float viewStart = view.getTranslationY(); int fullHeight = view.getActualHeight() + mPaddingBetweenElements; float iconTransformStart = calculateIconTransformationStart(view); float transformDistance = getIntrinsicHeight() * 1.5f; transformDistance *= NotificationUtils.interpolate(1.f, 1.5f, expandAmount); transformDistance = Math.min(transformDistance, fullHeight); // Let's make sure the transform distance is // at most to the icon (relevant for conversations) transformDistance = Math.min(viewStart + fullHeight - iconTransformStart, transformDistance); float transformDistance = Math.min( viewStart + fullHeight - iconTransformStart, getIntrinsicHeight()); if (isLastChild) { fullHeight = Math.min(fullHeight, view.getMinHeight() - getIntrinsicHeight()); transformDistance = Math.min(transformDistance, view.getMinHeight() - getIntrinsicHeight()); transformDistance = Math.min( transformDistance, view.getMinHeight() - getIntrinsicHeight()); } float viewEnd = viewStart + fullHeight; handleCustomTransformHeight(view, expandingAnimated, iconState); float fullTransitionAmount; float iconTransitionAmount; float contentTransformationAmount; float fullTransitionAmount = 0.0f; float iconTransitionAmount = 0.0f; float shelfStart = getTranslationY(); boolean fullyInOrOut = true; if (viewEnd >= shelfStart && (!mAmbientState.isUnlockHintRunning() || view.isInShelf()) if (viewEnd >= shelfStart && (!mAmbientState.isUnlockHintRunning() || view.isInShelf()) && (mAmbientState.isShadeExpanded() || (!view.isPinned() && !view.isHeadsUpAnimatingAway()))) { if (viewStart < shelfStart) { if (iconState != null && iconState.hasCustomTransformHeight()) { fullHeight = iconState.customTransformHeight; transformDistance = iconState.customTransformHeight; } if (viewStart < shelfStart) { float fullAmount = (shelfStart - viewStart) / fullHeight; fullAmount = Math.min(1.0f, fullAmount); float interpolatedAmount = Interpolators.ACCELERATE_DECELERATE.getInterpolation( fullAmount); interpolatedAmount = NotificationUtils.interpolate( interpolatedAmount, fullAmount, expandAmount); fullTransitionAmount = 1.0f - interpolatedAmount; fullTransitionAmount = 1.0f - fullAmount; if (isLastChild) { // Reduce icon transform distance to completely fade in shelf icon // by the time the notification icon fades out, and vice versa Loading @@ -558,37 +519,14 @@ public class NotificationShelf extends ActivatableNotificationView implements } iconTransitionAmount = MathUtils.constrain(iconTransitionAmount, 0.0f, 1.0f); iconTransitionAmount = 1.0f - iconTransitionAmount; fullyInOrOut = false; } else { // Fully in shelf. fullTransitionAmount = 1.0f; iconTransitionAmount = 1.0f; } // Transforming the content contentTransformationAmount = (shelfStart - viewStart) / transformDistance; contentTransformationAmount = Math.min(1.0f, contentTransformationAmount); contentTransformationAmount = 1.0f - contentTransformationAmount; } else { fullTransitionAmount = 0.0f; iconTransitionAmount = 0.0f; contentTransformationAmount = 0.0f; } if (iconState != null && fullyInOrOut && !expandingAnimated && iconState.isLastExpandIcon) { iconState.isLastExpandIcon = false; iconState.customTransformHeight = NO_VALUE; } // Update the content transformation amount if (view.isAboveShelf() || view.showingPulsing() || (!isLastChild && iconState != null && !iconState.translateContent)) { contentTransformationAmount = 0.0f; } view.setContentTransformationAmount(contentTransformationAmount, isLastChild); // Update the positioning of the icon updateIconPositioning(view, iconTransitionAmount, fullTransitionAmount, transformDistance, scrolling, scrollingFast, expandingAnimated, isLastChild); updateIconPositioning(view, iconTransitionAmount, scrollingFast, expandingAnimated, isLastChild); return fullTransitionAmount; } Loading @@ -607,87 +545,31 @@ public class NotificationShelf extends ActivatableNotificationView implements return start; } private void handleCustomTransformHeight(ExpandableView view, boolean expandingAnimated, NotificationIconContainer.IconState iconState) { if (iconState != null && 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() + mHostLayoutController.getPositionInLinearLayout(view); int maxShelfStart = mMaxLayoutHeight - getIntrinsicHeight(); if (position < maxShelfStart && position + view.getIntrinsicHeight() >= maxShelfStart && view.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); } } } } private void updateIconPositioning(ExpandableView view, float iconTransitionAmount, float fullTransitionAmount, float iconTransformDistance, boolean scrolling, boolean scrollingFast, boolean expandingAnimated, boolean isLastChild) { StatusBarIconView icon = view.getShelfIcon(); NotificationIconContainer.IconState iconState = getIconState(icon); if (iconState == null) { return; } boolean forceInShelf = iconState.isLastExpandIcon && !iconState.hasCustomTransformHeight(); boolean clampInShelf = iconTransitionAmount > 0.5f || isTargetClipped(view); float clampedAmount = clampInShelf ? 1.0f : 0.0f; if (iconTransitionAmount == clampedAmount) { iconState.noAnimations = (scrollingFast || expandingAnimated) && !forceInShelf; iconState.useFullTransitionAmount = iconState.noAnimations || (!ICON_ANMATIONS_WHILE_SCROLLING && iconTransitionAmount == 0.0f && scrolling); iconState.useLinearTransitionAmount = !ICON_ANMATIONS_WHILE_SCROLLING && iconTransitionAmount == 0.0f && !mAmbientState.isExpansionChanging(); iconState.translateContent = mMaxLayoutHeight - getTranslationY() - getIntrinsicHeight() > 0; } if (!forceInShelf && (scrollingFast || (expandingAnimated && iconState.useFullTransitionAmount && !ViewState.isAnimatingY(icon)))) { iconState.noAnimations = (scrollingFast || expandingAnimated) && !isLastChild; } if (!isLastChild && (scrollingFast || (expandingAnimated && !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 (mAmbientState.isHiddenAtAll() && !view.isInShelf()) { transitionAmount = mAmbientState.isFullyHidden() ? 1 : 0; } else if (isLastChild || !USE_ANIMATIONS_WHEN_OPENING || iconState.useFullTransitionAmount || iconState.useLinearTransitionAmount) { transitionAmount = iconTransitionAmount; } else { transitionAmount = iconTransitionAmount; iconState.needsCannedAnimation = iconState.clampedAppearAmount != clampedAmount && !mNoAnimationsInThisFrame; } iconState.iconAppearAmount = !USE_ANIMATIONS_WHEN_OPENING || iconState.useFullTransitionAmount ? fullTransitionAmount : transitionAmount; iconState.clampedAppearAmount = clampedAmount; setIconTransformationAmount(view, transitionAmount, isLastChild); } Loading @@ -706,8 +588,7 @@ public class NotificationShelf extends ActivatableNotificationView implements return endOfTarget >= getTranslationY() - mPaddingBetweenElements; } private void setIconTransformationAmount(ExpandableView view, float transitionAmount, private void setIconTransformationAmount(ExpandableView view, float transitionAmount, boolean isLastChild) { if (!(view instanceof ExpandableNotificationRow)) { return; Loading @@ -718,32 +599,30 @@ public class NotificationShelf extends ActivatableNotificationView implements if (iconState == null) { return; } iconState.hidden = transitionAmount == 0.0f && !iconState.isAnimating(icon); boolean isAppearing = row.isDrawingAppearAnimation() && !row.isInShelf(); if (isAppearing) { iconState.hidden = true; iconState.iconAppearAmount = 0.0f; } iconState.alpha = transitionAmount; boolean isAppearing = row.isDrawingAppearAnimation() && !row.isInShelf(); iconState.hidden = isAppearing || (view instanceof ExpandableNotificationRow && ((ExpandableNotificationRow) view).isLowPriority() && mShelfIcons.hasMaxNumDot()) || (transitionAmount == 0.0f && !iconState.isAnimating(icon)) || row.isAboveShelf() || row.showingPulsing() || (!row.isInShelf() && isLastChild) || row.getTranslationZ() > mAmbientState.getBaseZHeight(); iconState.iconAppearAmount = iconState.hidden? 0f : transitionAmount; // Fade in icons at shelf start // This is important for conversation icons, which are badged and need x reset iconState.xTranslation = mShelfIcons.getActualPaddingStart(); boolean stayingInShelf = row.isInShelf() && !row.isTransformingIntoShelf(); final boolean stayingInShelf = row.isInShelf() && !row.isTransformingIntoShelf(); if (stayingInShelf) { iconState.iconAppearAmount = 1.0f; iconState.alpha = 1.0f; iconState.scaleX = 1.0f; iconState.scaleY = 1.0f; iconState.hidden = false; } if (row.isAboveShelf() || row.showingPulsing() || (!row.isInShelf() && (isLastChild && row.areGutsExposed() || row.getTranslationZ() > mAmbientState.getBaseZHeight()))) { iconState.hidden = true; } int backgroundColor = getBackgroundColorWithoutTint(); int shelfColor = icon.getContrastedStaticDrawableColor(backgroundColor); if (row.isShowingIcon() && shelfColor != StatusBarIconView.NO_COLOR) { Loading Loading @@ -819,42 +698,6 @@ public class NotificationShelf extends ActivatableNotificationView implements return ret; } private void setOpenedAmount(float openedAmount) { mNoAnimationsInThisFrame = openedAmount == 1.0f && mOpenedAmount == 0.0f; mOpenedAmount = openedAmount; if (!mAmbientState.isPanelFullWidth() || mAmbientState.isDozing()) { // We don't do a transformation at all, lets just assume we are fully opened openedAmount = 1.0f; } int start = mRelativeOffset; if (isLayoutRtl()) { start = getWidth() - start - mCollapsedIcons.getWidth(); } int width = (int) NotificationUtils.interpolate( start + mCollapsedIcons.getFinalTranslationX(), mShelfIcons.getWidth(), FAST_OUT_SLOW_IN_REVERSE.getInterpolation(openedAmount)); mShelfIcons.setActualLayoutWidth(width); boolean hasOverflow = mCollapsedIcons.hasOverflow(); int collapsedPadding = mCollapsedIcons.getPaddingEnd(); if (!hasOverflow) { // we have to ensure that adding the low priority notification won't lead to an // overflow collapsedPadding -= mCollapsedIcons.getNoOverflowExtraPadding(); } else { // Partial overflow padding will fill enough space to add extra dots collapsedPadding -= mCollapsedIcons.getPartialOverflowExtraPadding(); } float padding = NotificationUtils.interpolate(collapsedPadding, mShelfIcons.getPaddingEnd(), openedAmount); mShelfIcons.setActualPaddingEnd(padding); float paddingStart = NotificationUtils.interpolate(start, mShelfIcons.getPaddingStart(), openedAmount); mShelfIcons.setActualPaddingStart(paddingStart); mShelfIcons.setOpenedAmount(openedAmount); } public void setMaxLayoutHeight(int maxLayoutHeight) { mMaxLayoutHeight = maxLayoutHeight; } Loading Loading @@ -947,7 +790,6 @@ public class NotificationShelf extends ActivatableNotificationView implements } private class ShelfState extends ExpandableViewState { private float openedAmount; private boolean hasItemsInStableShelf; @Override Loading @@ -957,7 +799,6 @@ public class NotificationShelf extends ActivatableNotificationView implements } super.applyToView(view); setOpenedAmount(openedAmount); updateAppearance(); setHasItemsInStableShelf(hasItemsInStableShelf); mShelfIcons.setAnimationsEnabled(mAnimationsEnabled); Loading @@ -970,7 +811,6 @@ public class NotificationShelf extends ActivatableNotificationView implements } super.animateTo(child, properties); setOpenedAmount(openedAmount); updateAppearance(); setHasItemsInStableShelf(hasItemsInStableShelf); mShelfIcons.setAnimationsEnabled(mAnimationsEnabled); Loading packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java +16 −21 Original line number Diff line number Diff line Loading @@ -155,7 +155,6 @@ public class NotificationIconContainer extends AlphaOptimizedFrameLayout { private int mCannedAnimationStartIndex = -1; private int mSpeedBumpIndex = -1; private int mIconSize; private float mOpenedAmount = 0.0f; private boolean mDisallowNextAnimation; private boolean mAnimationsEnabled = true; private ArrayMap<String, ArrayList<StatusBarIcon>> mReplacingIcons; Loading Loading @@ -349,6 +348,10 @@ public class NotificationIconContainer extends AlphaOptimizedFrameLayout { } } public boolean hasMaxNumDot() { return mNumDots >= MAX_DOTS; } private boolean areAnimationsEnabled(StatusBarIconView icon) { return mAnimationsEnabled || icon == mIsolatedIcon; } Loading Loading @@ -391,7 +394,6 @@ public class NotificationIconContainer extends AlphaOptimizedFrameLayout { float overflowStart = getMaxOverflowStart(); mVisualOverflowStart = 0; mFirstVisibleIconState = null; boolean hasAmbient = mSpeedBumpIndex != -1 && mSpeedBumpIndex < getChildCount(); for (int i = 0; i < childCount; i++) { View view = getChildAt(i); IconState iconState = mIconStates.get(view); Loading @@ -410,10 +412,9 @@ public class NotificationIconContainer extends AlphaOptimizedFrameLayout { float drawingScale = mOnLockScreen && view instanceof StatusBarIconView ? ((StatusBarIconView) view).getIconScaleIncreased() : 1f; if (mOpenedAmount != 0.0f) { noOverflowAfter = noOverflowAfter && !hasAmbient && !forceOverflow; } iconState.visibleState = StatusBarIconView.STATE_ICON; iconState.visibleState = iconState.hidden ? StatusBarIconView.STATE_HIDDEN : StatusBarIconView.STATE_ICON; boolean isOverflowing = (translationX > (noOverflowAfter ? layoutEnd - mIconSize Loading Loading @@ -598,10 +599,6 @@ public class NotificationIconContainer extends AlphaOptimizedFrameLayout { mSpeedBumpIndex = speedBumpIndex; } public void setOpenedAmount(float expandAmount) { mOpenedAmount = expandAmount; } public boolean hasOverflow() { return mNumDots > 0; } Loading Loading @@ -706,13 +703,8 @@ public class NotificationIconContainer extends AlphaOptimizedFrameLayout { public boolean justAdded = true; private boolean justReplaced; public boolean needsCannedAnimation; public boolean useFullTransitionAmount; public boolean useLinearTransitionAmount; public boolean translateContent; public int iconColor = StatusBarIconView.NO_COLOR; public boolean noAnimations; public boolean isLastExpandIcon; public int customTransformHeight = NO_VALUE; private final View mView; private final Consumer<Property> mCannedAnimationEndListener; Loading @@ -734,8 +726,15 @@ public class NotificationIconContainer extends AlphaOptimizedFrameLayout { StatusBarIconView icon = (StatusBarIconView) view; boolean animate = false; AnimationProperties animationProperties = null; boolean animationsAllowed = areAnimationsEnabled(icon) && !mDisallowNextAnimation && !noAnimations; final boolean isLowPriorityIconChange = (visibleState == StatusBarIconView.STATE_HIDDEN && icon.getVisibleState() == StatusBarIconView.STATE_DOT) || (visibleState == StatusBarIconView.STATE_DOT && icon.getVisibleState() == StatusBarIconView.STATE_HIDDEN); final boolean animationsAllowed = areAnimationsEnabled(icon) && !mDisallowNextAnimation && !noAnimations && !isLowPriorityIconChange; if (animationsAllowed) { if (justAdded || justReplaced) { super.applyToView(icon); Loading Loading @@ -822,10 +821,6 @@ public class NotificationIconContainer extends AlphaOptimizedFrameLayout { needsCannedAnimation = false; } public boolean hasCustomTransformHeight() { return isLastExpandIcon && customTransformHeight != NO_VALUE; } @Override public void initFrom(View view) { super.initFrom(view); Loading Loading
packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java +39 −199 Original line number Diff line number Diff line Loading @@ -16,9 +16,6 @@ package com.android.systemui.statusbar; import static com.android.systemui.Interpolators.FAST_OUT_SLOW_IN_REVERSE; import static com.android.systemui.statusbar.phone.NotificationIconContainer.IconState.NO_VALUE; import android.content.Context; import android.content.res.Configuration; import android.content.res.Resources; Loading @@ -34,7 +31,6 @@ import android.view.WindowInsets; import android.view.accessibility.AccessibilityNodeInfo; import com.android.internal.annotations.VisibleForTesting; import com.android.systemui.Interpolators; import com.android.systemui.R; import com.android.systemui.plugins.statusbar.StatusBarStateController.StateListener; import com.android.systemui.statusbar.notification.NotificationUtils; Loading @@ -55,8 +51,6 @@ import com.android.systemui.statusbar.phone.NotificationIconContainer; public class NotificationShelf extends ActivatableNotificationView implements View.OnLayoutChangeListener, StateListener { private static final boolean USE_ANIMATIONS_WHEN_OPENING = 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; Loading Loading @@ -174,18 +168,9 @@ public class NotificationShelf extends ActivatableNotificationView implements float viewEnd = lastViewState.yTranslation + lastViewState.height; viewState.copyFrom(lastViewState); viewState.height = getIntrinsicHeight(); viewState.yTranslation = Math.max(Math.min(viewEnd, maxShelfEnd) - viewState.height, getFullyClosedTranslation()); viewState.zTranslation = ambientState.getBaseZHeight(); // For the small display size, it's not enough to make the icon not covered by // the top cutout so the denominator add the height of cutout. // Totally, (getIntrinsicHeight() * 2 + mCutoutHeight) should be smaller then // mAmbientState.getTopPadding(). float openedAmount = (viewState.yTranslation - getFullyClosedTranslation()) / (getIntrinsicHeight() * 2 + mCutoutHeight); openedAmount = Math.min(1.0f, openedAmount); viewState.openedAmount = openedAmount; viewState.clipTopAmount = 0; viewState.alpha = 1; viewState.belowSpeedBump = mHostLayoutController.getSpeedBumpIndex() == 0; Loading Loading @@ -220,11 +205,6 @@ public class NotificationShelf extends ActivatableNotificationView implements View lastChild = mAmbientState.getLastVisibleBackgroundChild(); mNotGoneIndex = -1; float interpolationStart = mMaxLayoutHeight - getIntrinsicHeight() * 2; float expandAmount = 0.0f; if (shelfStart >= interpolationStart) { expandAmount = (shelfStart - interpolationStart) / getIntrinsicHeight(); expandAmount = Math.min(1.0f, expandAmount); } // find the first view that doesn't overlap with the shelf int notGoneIndex = 0; int colorOfViewBeforeLast = NO_COLOR; Loading @@ -239,7 +219,6 @@ public class NotificationShelf extends ActivatableNotificationView implements boolean scrollingFast = currentScrollVelocity > mScrollFastThreshold || (mAmbientState.isExpansionChanging() && Math.abs(mAmbientState.getExpandingVelocity()) > mScrollFastThreshold); boolean scrolling = currentScrollVelocity > 0; boolean expandingAnimated = mAmbientState.isExpansionChanging() && !mAmbientState.isPanelTracking(); int baseZHeight = mAmbientState.getBaseZHeight(); Loading @@ -249,8 +228,7 @@ public class NotificationShelf extends ActivatableNotificationView implements ActivatableNotificationView previousAnv = null; for (int i = 0; i < mHostLayoutController.getChildCount(); i++) { ExpandableView child = (ExpandableView) mHostLayoutController.getChildAt(i); ExpandableView child = mHostLayoutController.getChildAt(i); if (!child.needsClippingToShelf() || child.getVisibility() == GONE) { continue; } Loading @@ -268,9 +246,8 @@ public class NotificationShelf extends ActivatableNotificationView implements int clipTop = updateNotificationClipHeight(child, notificationClipEnd, notGoneIndex); clipTopAmount = Math.max(clipTop, clipTopAmount); float inShelfAmount = updateShelfTransformation(child, expandAmount, scrolling, scrollingFast, expandingAnimated, isLastChild); final float inShelfAmount = updateShelfTransformation(child, scrollingFast, expandingAnimated, isLastChild); // If the current row is an ExpandableNotificationRow, update its color, roundedness, // and icon state. if (child instanceof ExpandableNotificationRow) { Loading Loading @@ -498,56 +475,40 @@ public class NotificationShelf extends ActivatableNotificationView implements /** * @return the amount how much this notification is in the shelf */ private float updateShelfTransformation(ExpandableView view, float expandAmount, boolean scrolling, boolean scrollingFast, boolean expandingAnimated, boolean isLastChild) { StatusBarIconView icon = view.getShelfIcon(); NotificationIconContainer.IconState iconState = getIconState(icon); private float updateShelfTransformation(ExpandableView view, boolean scrollingFast, boolean expandingAnimated, boolean isLastChild) { // Let calculate how much the view is in the shelf float viewStart = view.getTranslationY(); int fullHeight = view.getActualHeight() + mPaddingBetweenElements; float iconTransformStart = calculateIconTransformationStart(view); float transformDistance = getIntrinsicHeight() * 1.5f; transformDistance *= NotificationUtils.interpolate(1.f, 1.5f, expandAmount); transformDistance = Math.min(transformDistance, fullHeight); // Let's make sure the transform distance is // at most to the icon (relevant for conversations) transformDistance = Math.min(viewStart + fullHeight - iconTransformStart, transformDistance); float transformDistance = Math.min( viewStart + fullHeight - iconTransformStart, getIntrinsicHeight()); if (isLastChild) { fullHeight = Math.min(fullHeight, view.getMinHeight() - getIntrinsicHeight()); transformDistance = Math.min(transformDistance, view.getMinHeight() - getIntrinsicHeight()); transformDistance = Math.min( transformDistance, view.getMinHeight() - getIntrinsicHeight()); } float viewEnd = viewStart + fullHeight; handleCustomTransformHeight(view, expandingAnimated, iconState); float fullTransitionAmount; float iconTransitionAmount; float contentTransformationAmount; float fullTransitionAmount = 0.0f; float iconTransitionAmount = 0.0f; float shelfStart = getTranslationY(); boolean fullyInOrOut = true; if (viewEnd >= shelfStart && (!mAmbientState.isUnlockHintRunning() || view.isInShelf()) if (viewEnd >= shelfStart && (!mAmbientState.isUnlockHintRunning() || view.isInShelf()) && (mAmbientState.isShadeExpanded() || (!view.isPinned() && !view.isHeadsUpAnimatingAway()))) { if (viewStart < shelfStart) { if (iconState != null && iconState.hasCustomTransformHeight()) { fullHeight = iconState.customTransformHeight; transformDistance = iconState.customTransformHeight; } if (viewStart < shelfStart) { float fullAmount = (shelfStart - viewStart) / fullHeight; fullAmount = Math.min(1.0f, fullAmount); float interpolatedAmount = Interpolators.ACCELERATE_DECELERATE.getInterpolation( fullAmount); interpolatedAmount = NotificationUtils.interpolate( interpolatedAmount, fullAmount, expandAmount); fullTransitionAmount = 1.0f - interpolatedAmount; fullTransitionAmount = 1.0f - fullAmount; if (isLastChild) { // Reduce icon transform distance to completely fade in shelf icon // by the time the notification icon fades out, and vice versa Loading @@ -558,37 +519,14 @@ public class NotificationShelf extends ActivatableNotificationView implements } iconTransitionAmount = MathUtils.constrain(iconTransitionAmount, 0.0f, 1.0f); iconTransitionAmount = 1.0f - iconTransitionAmount; fullyInOrOut = false; } else { // Fully in shelf. fullTransitionAmount = 1.0f; iconTransitionAmount = 1.0f; } // Transforming the content contentTransformationAmount = (shelfStart - viewStart) / transformDistance; contentTransformationAmount = Math.min(1.0f, contentTransformationAmount); contentTransformationAmount = 1.0f - contentTransformationAmount; } else { fullTransitionAmount = 0.0f; iconTransitionAmount = 0.0f; contentTransformationAmount = 0.0f; } if (iconState != null && fullyInOrOut && !expandingAnimated && iconState.isLastExpandIcon) { iconState.isLastExpandIcon = false; iconState.customTransformHeight = NO_VALUE; } // Update the content transformation amount if (view.isAboveShelf() || view.showingPulsing() || (!isLastChild && iconState != null && !iconState.translateContent)) { contentTransformationAmount = 0.0f; } view.setContentTransformationAmount(contentTransformationAmount, isLastChild); // Update the positioning of the icon updateIconPositioning(view, iconTransitionAmount, fullTransitionAmount, transformDistance, scrolling, scrollingFast, expandingAnimated, isLastChild); updateIconPositioning(view, iconTransitionAmount, scrollingFast, expandingAnimated, isLastChild); return fullTransitionAmount; } Loading @@ -607,87 +545,31 @@ public class NotificationShelf extends ActivatableNotificationView implements return start; } private void handleCustomTransformHeight(ExpandableView view, boolean expandingAnimated, NotificationIconContainer.IconState iconState) { if (iconState != null && 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() + mHostLayoutController.getPositionInLinearLayout(view); int maxShelfStart = mMaxLayoutHeight - getIntrinsicHeight(); if (position < maxShelfStart && position + view.getIntrinsicHeight() >= maxShelfStart && view.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); } } } } private void updateIconPositioning(ExpandableView view, float iconTransitionAmount, float fullTransitionAmount, float iconTransformDistance, boolean scrolling, boolean scrollingFast, boolean expandingAnimated, boolean isLastChild) { StatusBarIconView icon = view.getShelfIcon(); NotificationIconContainer.IconState iconState = getIconState(icon); if (iconState == null) { return; } boolean forceInShelf = iconState.isLastExpandIcon && !iconState.hasCustomTransformHeight(); boolean clampInShelf = iconTransitionAmount > 0.5f || isTargetClipped(view); float clampedAmount = clampInShelf ? 1.0f : 0.0f; if (iconTransitionAmount == clampedAmount) { iconState.noAnimations = (scrollingFast || expandingAnimated) && !forceInShelf; iconState.useFullTransitionAmount = iconState.noAnimations || (!ICON_ANMATIONS_WHILE_SCROLLING && iconTransitionAmount == 0.0f && scrolling); iconState.useLinearTransitionAmount = !ICON_ANMATIONS_WHILE_SCROLLING && iconTransitionAmount == 0.0f && !mAmbientState.isExpansionChanging(); iconState.translateContent = mMaxLayoutHeight - getTranslationY() - getIntrinsicHeight() > 0; } if (!forceInShelf && (scrollingFast || (expandingAnimated && iconState.useFullTransitionAmount && !ViewState.isAnimatingY(icon)))) { iconState.noAnimations = (scrollingFast || expandingAnimated) && !isLastChild; } if (!isLastChild && (scrollingFast || (expandingAnimated && !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 (mAmbientState.isHiddenAtAll() && !view.isInShelf()) { transitionAmount = mAmbientState.isFullyHidden() ? 1 : 0; } else if (isLastChild || !USE_ANIMATIONS_WHEN_OPENING || iconState.useFullTransitionAmount || iconState.useLinearTransitionAmount) { transitionAmount = iconTransitionAmount; } else { transitionAmount = iconTransitionAmount; iconState.needsCannedAnimation = iconState.clampedAppearAmount != clampedAmount && !mNoAnimationsInThisFrame; } iconState.iconAppearAmount = !USE_ANIMATIONS_WHEN_OPENING || iconState.useFullTransitionAmount ? fullTransitionAmount : transitionAmount; iconState.clampedAppearAmount = clampedAmount; setIconTransformationAmount(view, transitionAmount, isLastChild); } Loading @@ -706,8 +588,7 @@ public class NotificationShelf extends ActivatableNotificationView implements return endOfTarget >= getTranslationY() - mPaddingBetweenElements; } private void setIconTransformationAmount(ExpandableView view, float transitionAmount, private void setIconTransformationAmount(ExpandableView view, float transitionAmount, boolean isLastChild) { if (!(view instanceof ExpandableNotificationRow)) { return; Loading @@ -718,32 +599,30 @@ public class NotificationShelf extends ActivatableNotificationView implements if (iconState == null) { return; } iconState.hidden = transitionAmount == 0.0f && !iconState.isAnimating(icon); boolean isAppearing = row.isDrawingAppearAnimation() && !row.isInShelf(); if (isAppearing) { iconState.hidden = true; iconState.iconAppearAmount = 0.0f; } iconState.alpha = transitionAmount; boolean isAppearing = row.isDrawingAppearAnimation() && !row.isInShelf(); iconState.hidden = isAppearing || (view instanceof ExpandableNotificationRow && ((ExpandableNotificationRow) view).isLowPriority() && mShelfIcons.hasMaxNumDot()) || (transitionAmount == 0.0f && !iconState.isAnimating(icon)) || row.isAboveShelf() || row.showingPulsing() || (!row.isInShelf() && isLastChild) || row.getTranslationZ() > mAmbientState.getBaseZHeight(); iconState.iconAppearAmount = iconState.hidden? 0f : transitionAmount; // Fade in icons at shelf start // This is important for conversation icons, which are badged and need x reset iconState.xTranslation = mShelfIcons.getActualPaddingStart(); boolean stayingInShelf = row.isInShelf() && !row.isTransformingIntoShelf(); final boolean stayingInShelf = row.isInShelf() && !row.isTransformingIntoShelf(); if (stayingInShelf) { iconState.iconAppearAmount = 1.0f; iconState.alpha = 1.0f; iconState.scaleX = 1.0f; iconState.scaleY = 1.0f; iconState.hidden = false; } if (row.isAboveShelf() || row.showingPulsing() || (!row.isInShelf() && (isLastChild && row.areGutsExposed() || row.getTranslationZ() > mAmbientState.getBaseZHeight()))) { iconState.hidden = true; } int backgroundColor = getBackgroundColorWithoutTint(); int shelfColor = icon.getContrastedStaticDrawableColor(backgroundColor); if (row.isShowingIcon() && shelfColor != StatusBarIconView.NO_COLOR) { Loading Loading @@ -819,42 +698,6 @@ public class NotificationShelf extends ActivatableNotificationView implements return ret; } private void setOpenedAmount(float openedAmount) { mNoAnimationsInThisFrame = openedAmount == 1.0f && mOpenedAmount == 0.0f; mOpenedAmount = openedAmount; if (!mAmbientState.isPanelFullWidth() || mAmbientState.isDozing()) { // We don't do a transformation at all, lets just assume we are fully opened openedAmount = 1.0f; } int start = mRelativeOffset; if (isLayoutRtl()) { start = getWidth() - start - mCollapsedIcons.getWidth(); } int width = (int) NotificationUtils.interpolate( start + mCollapsedIcons.getFinalTranslationX(), mShelfIcons.getWidth(), FAST_OUT_SLOW_IN_REVERSE.getInterpolation(openedAmount)); mShelfIcons.setActualLayoutWidth(width); boolean hasOverflow = mCollapsedIcons.hasOverflow(); int collapsedPadding = mCollapsedIcons.getPaddingEnd(); if (!hasOverflow) { // we have to ensure that adding the low priority notification won't lead to an // overflow collapsedPadding -= mCollapsedIcons.getNoOverflowExtraPadding(); } else { // Partial overflow padding will fill enough space to add extra dots collapsedPadding -= mCollapsedIcons.getPartialOverflowExtraPadding(); } float padding = NotificationUtils.interpolate(collapsedPadding, mShelfIcons.getPaddingEnd(), openedAmount); mShelfIcons.setActualPaddingEnd(padding); float paddingStart = NotificationUtils.interpolate(start, mShelfIcons.getPaddingStart(), openedAmount); mShelfIcons.setActualPaddingStart(paddingStart); mShelfIcons.setOpenedAmount(openedAmount); } public void setMaxLayoutHeight(int maxLayoutHeight) { mMaxLayoutHeight = maxLayoutHeight; } Loading Loading @@ -947,7 +790,6 @@ public class NotificationShelf extends ActivatableNotificationView implements } private class ShelfState extends ExpandableViewState { private float openedAmount; private boolean hasItemsInStableShelf; @Override Loading @@ -957,7 +799,6 @@ public class NotificationShelf extends ActivatableNotificationView implements } super.applyToView(view); setOpenedAmount(openedAmount); updateAppearance(); setHasItemsInStableShelf(hasItemsInStableShelf); mShelfIcons.setAnimationsEnabled(mAnimationsEnabled); Loading @@ -970,7 +811,6 @@ public class NotificationShelf extends ActivatableNotificationView implements } super.animateTo(child, properties); setOpenedAmount(openedAmount); updateAppearance(); setHasItemsInStableShelf(hasItemsInStableShelf); mShelfIcons.setAnimationsEnabled(mAnimationsEnabled); Loading
packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java +16 −21 Original line number Diff line number Diff line Loading @@ -155,7 +155,6 @@ public class NotificationIconContainer extends AlphaOptimizedFrameLayout { private int mCannedAnimationStartIndex = -1; private int mSpeedBumpIndex = -1; private int mIconSize; private float mOpenedAmount = 0.0f; private boolean mDisallowNextAnimation; private boolean mAnimationsEnabled = true; private ArrayMap<String, ArrayList<StatusBarIcon>> mReplacingIcons; Loading Loading @@ -349,6 +348,10 @@ public class NotificationIconContainer extends AlphaOptimizedFrameLayout { } } public boolean hasMaxNumDot() { return mNumDots >= MAX_DOTS; } private boolean areAnimationsEnabled(StatusBarIconView icon) { return mAnimationsEnabled || icon == mIsolatedIcon; } Loading Loading @@ -391,7 +394,6 @@ public class NotificationIconContainer extends AlphaOptimizedFrameLayout { float overflowStart = getMaxOverflowStart(); mVisualOverflowStart = 0; mFirstVisibleIconState = null; boolean hasAmbient = mSpeedBumpIndex != -1 && mSpeedBumpIndex < getChildCount(); for (int i = 0; i < childCount; i++) { View view = getChildAt(i); IconState iconState = mIconStates.get(view); Loading @@ -410,10 +412,9 @@ public class NotificationIconContainer extends AlphaOptimizedFrameLayout { float drawingScale = mOnLockScreen && view instanceof StatusBarIconView ? ((StatusBarIconView) view).getIconScaleIncreased() : 1f; if (mOpenedAmount != 0.0f) { noOverflowAfter = noOverflowAfter && !hasAmbient && !forceOverflow; } iconState.visibleState = StatusBarIconView.STATE_ICON; iconState.visibleState = iconState.hidden ? StatusBarIconView.STATE_HIDDEN : StatusBarIconView.STATE_ICON; boolean isOverflowing = (translationX > (noOverflowAfter ? layoutEnd - mIconSize Loading Loading @@ -598,10 +599,6 @@ public class NotificationIconContainer extends AlphaOptimizedFrameLayout { mSpeedBumpIndex = speedBumpIndex; } public void setOpenedAmount(float expandAmount) { mOpenedAmount = expandAmount; } public boolean hasOverflow() { return mNumDots > 0; } Loading Loading @@ -706,13 +703,8 @@ public class NotificationIconContainer extends AlphaOptimizedFrameLayout { public boolean justAdded = true; private boolean justReplaced; public boolean needsCannedAnimation; public boolean useFullTransitionAmount; public boolean useLinearTransitionAmount; public boolean translateContent; public int iconColor = StatusBarIconView.NO_COLOR; public boolean noAnimations; public boolean isLastExpandIcon; public int customTransformHeight = NO_VALUE; private final View mView; private final Consumer<Property> mCannedAnimationEndListener; Loading @@ -734,8 +726,15 @@ public class NotificationIconContainer extends AlphaOptimizedFrameLayout { StatusBarIconView icon = (StatusBarIconView) view; boolean animate = false; AnimationProperties animationProperties = null; boolean animationsAllowed = areAnimationsEnabled(icon) && !mDisallowNextAnimation && !noAnimations; final boolean isLowPriorityIconChange = (visibleState == StatusBarIconView.STATE_HIDDEN && icon.getVisibleState() == StatusBarIconView.STATE_DOT) || (visibleState == StatusBarIconView.STATE_DOT && icon.getVisibleState() == StatusBarIconView.STATE_HIDDEN); final boolean animationsAllowed = areAnimationsEnabled(icon) && !mDisallowNextAnimation && !noAnimations && !isLowPriorityIconChange; if (animationsAllowed) { if (justAdded || justReplaced) { super.applyToView(icon); Loading Loading @@ -822,10 +821,6 @@ public class NotificationIconContainer extends AlphaOptimizedFrameLayout { needsCannedAnimation = false; } public boolean hasCustomTransformHeight() { return isLastExpandIcon && customTransformHeight != NO_VALUE; } @Override public void initFrom(View view) { super.initFrom(view); Loading