diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/DismissView.java b/packages/SystemUI/src/com/android/systemui/statusbar/DismissView.java index 1d7bede962d3f..543666407fb9a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/DismissView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/DismissView.java @@ -22,12 +22,17 @@ import android.util.AttributeSet; import android.view.View; import com.android.systemui.R; +import com.android.systemui.statusbar.stack.ExpandableViewState; +import com.android.systemui.statusbar.stack.StackScrollState; public class DismissView extends StackScrollerDecorView { + private final int mClearAllTopPadding; private DismissViewButton mDismissButton; public DismissView(Context context, AttributeSet attrs) { super(context, attrs); + mClearAllTopPadding = context.getResources().getDimensionPixelSize( + R.dimen.clear_all_padding_top); } @Override @@ -63,4 +68,21 @@ public class DismissView extends StackScrollerDecorView { public boolean isButtonVisible() { return mDismissButton.getAlpha() != 0.0f; } + + @Override + public ExpandableViewState createNewViewState(StackScrollState stackScrollState) { + return new DismissViewState(); + } + + public class DismissViewState extends ExpandableViewState { + @Override + public void applyToView(View view) { + super.applyToView(view); + if (view instanceof DismissView) { + DismissView dismissView = (DismissView) view; + boolean visible = this.clipTopAmount < mClearAllTopPadding; + dismissView.performVisibilityAnimation(visible && !dismissView.willBeGone()); + } + } + } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/EmptyShadeView.java b/packages/SystemUI/src/com/android/systemui/statusbar/EmptyShadeView.java index 5db06997eda56..19b32af8b9197 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/EmptyShadeView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/EmptyShadeView.java @@ -23,6 +23,8 @@ import android.view.View; import android.widget.TextView; import com.android.systemui.R; +import com.android.systemui.statusbar.stack.ExpandableViewState; +import com.android.systemui.statusbar.stack.StackScrollState; public class EmptyShadeView extends StackScrollerDecorView { @@ -40,4 +42,22 @@ public class EmptyShadeView extends StackScrollerDecorView { protected View findContentView() { return findViewById(R.id.no_notifications); } + + @Override + public ExpandableViewState createNewViewState(StackScrollState stackScrollState) { + return new EmptyShadeViewState(); + } + + public static class EmptyShadeViewState extends ExpandableViewState { + @Override + public void applyToView(View view) { + super.applyToView(view); + if (view instanceof EmptyShadeView) { + EmptyShadeView emptyShadeView = (EmptyShadeView) view; + boolean visible = this.clipTopAmount <= 0; + emptyShadeView.performVisibilityAnimation( + visible && !emptyShadeView.willBeGone()); + } + } + } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java index 5173176ffa8f3..c9a5fdf374d7e 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java @@ -54,7 +54,7 @@ import com.android.systemui.statusbar.stack.NotificationChildrenContainer; import com.android.systemui.statusbar.stack.NotificationStackScrollLayout; import com.android.systemui.statusbar.stack.StackScrollState; import com.android.systemui.statusbar.stack.StackStateAnimator; -import com.android.systemui.statusbar.stack.StackViewState; +import com.android.systemui.statusbar.stack.ExpandableViewState; import java.util.ArrayList; import java.util.List; @@ -459,7 +459,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView { public void getChildrenStates(StackScrollState resultState) { if (mIsSummaryWithChildren) { - StackViewState parentState = resultState.getViewStateForView(this); + ExpandableViewState parentState = resultState.getViewStateForView(this); mChildrenContainer.getState(resultState, parentState); } } @@ -1679,4 +1679,30 @@ public class ExpandableNotificationRow extends ActivatableNotificationView { public interface OnExpandClickListener { void onExpandClicked(NotificationData.Entry clickedEntry, boolean nowExpanded); } + + @Override + public ExpandableViewState createNewViewState(StackScrollState stackScrollState) { + return new NotificationViewState(stackScrollState); + } + + public static class NotificationViewState extends ExpandableViewState { + + private final StackScrollState mOverallState; + + private NotificationViewState(StackScrollState stackScrollState) { + mOverallState = stackScrollState; + } + + @Override + public void applyToView(View view) { + super.applyToView(view); + if (view instanceof ExpandableNotificationRow) { + ExpandableNotificationRow row = (ExpandableNotificationRow) view; + if (this.isBottomClipped) { + row.setClipToActualHeight(true); + } + row.applyChildrenState(mOverallState); + } + } + } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java index 83b0ee0796399..b97d34579fd75 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java @@ -25,6 +25,8 @@ import android.view.ViewGroup; import android.widget.FrameLayout; import com.android.systemui.statusbar.stack.NotificationStackScrollLayout; +import com.android.systemui.statusbar.stack.ExpandableViewState; +import com.android.systemui.statusbar.stack.StackScrollState; import java.util.ArrayList; @@ -438,6 +440,10 @@ public abstract class ExpandableView extends FrameLayout { public void setActualHeightAnimating(boolean animating) {} + public ExpandableViewState createNewViewState(StackScrollState stackScrollState) { + return new ExpandableViewState(); + } + /** * A listener notifying when {@link #getActualHeight} changes. */ 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 6f13ba50b22fc..9b935273adb5e 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java @@ -197,7 +197,7 @@ import com.android.systemui.statusbar.stack.NotificationStackScrollLayout; import com.android.systemui.statusbar.stack.NotificationStackScrollLayout .OnChildLocationsChangedListener; import com.android.systemui.statusbar.stack.StackStateAnimator; -import com.android.systemui.statusbar.stack.StackViewState; +import com.android.systemui.statusbar.stack.ExpandableViewState; import com.android.systemui.volume.VolumeComponent; import java.io.FileDescriptor; @@ -569,8 +569,8 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, */ protected boolean mStartedGoingToSleep; - private static final int VISIBLE_LOCATIONS = StackViewState.LOCATION_FIRST_HUN - | StackViewState.LOCATION_MAIN_AREA; + private static final int VISIBLE_LOCATIONS = ExpandableViewState.LOCATION_FIRST_HUN + | ExpandableViewState.LOCATION_MAIN_AREA; private final OnChildLocationsChangedListener mNotificationLocationsChangedListener = new OnChildLocationsChangedListener() { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackViewState.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/ExpandableViewState.java similarity index 50% rename from packages/SystemUI/src/com/android/systemui/statusbar/stack/StackViewState.java rename to packages/SystemUI/src/com/android/systemui/statusbar/stack/ExpandableViewState.java index ecdee4eaecbac..02b7ce33ddb4e 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackViewState.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/ExpandableViewState.java @@ -16,20 +16,51 @@ package com.android.systemui.statusbar.stack; +import android.view.View; + +import com.android.systemui.statusbar.ExpandableView; + /** * A state of an expandable view */ -public class StackViewState extends ViewState { +public class ExpandableViewState extends ViewState { // These are flags such that we can create masks for filtering. + /** + * No known location. This is the default and should not be set after an invocation of the + * algorithm. + */ public static final int LOCATION_UNKNOWN = 0x00; + + /** + * The location is the first heads up notification, so on the very top. + */ public static final int LOCATION_FIRST_HUN = 0x01; + + /** + * The location is hidden / scrolled away on the top. + */ public static final int LOCATION_HIDDEN_TOP = 0x02; + + /** + * The location is in the main area of the screen and visible. + */ public static final int LOCATION_MAIN_AREA = 0x04; + + /** + * The location is in the bottom stack and it's peeking + */ public static final int LOCATION_BOTTOM_STACK_PEEKING = 0x08; + + /** + * The location is in the bottom stack and it's hidden. + */ public static final int LOCATION_BOTTOM_STACK_HIDDEN = 0x10; - /** The view isn't layouted at all. */ + + /** + * The view isn't layouted at all. + * */ public static final int LOCATION_GONE = 0x40; public int height; @@ -65,8 +96,8 @@ public class StackViewState extends ViewState { @Override public void copyFrom(ViewState viewState) { super.copyFrom(viewState); - if (viewState instanceof StackViewState) { - StackViewState svs = (StackViewState) viewState; + if (viewState instanceof ExpandableViewState) { + ExpandableViewState svs = (ExpandableViewState) viewState; height = svs.height; dimmed = svs.dimmed; shadowAlpha = svs.shadowAlpha; @@ -79,4 +110,50 @@ public class StackViewState extends ViewState { isBottomClipped = svs.isBottomClipped; } } + + /** + * Applies a {@link ExpandableViewState} to a {@link ExpandableView}. + */ + @Override + public void applyToView(View view) { + super.applyToView(view); + if (view instanceof ExpandableView) { + ExpandableView expandableView = (ExpandableView) view; + + int height = expandableView.getActualHeight(); + int newHeight = this.height; + + // apply height + if (height != newHeight) { + expandableView.setActualHeight(newHeight, false /* notifyListeners */); + } + + float shadowAlpha = expandableView.getShadowAlpha(); + float newShadowAlpha = this.shadowAlpha; + + // apply shadowAlpha + if (shadowAlpha != newShadowAlpha) { + expandableView.setShadowAlpha(newShadowAlpha); + } + + // apply dimming + expandableView.setDimmed(this.dimmed, false /* animate */); + + // apply hiding sensitive + expandableView.setHideSensitive( + this.hideSensitive, false /* animated */, 0 /* delay */, 0 /* duration */); + + // apply below shelf speedBump + expandableView.setBelowSpeedBump(this.belowSpeedBump); + + // apply dark + expandableView.setDark(this.dark, false /* animate */, 0 /* delay */); + + // apply clipping + float oldClipTopAmount = expandableView.getClipTopAmount(); + if (oldClipTopAmount != this.clipTopAmount) { + expandableView.setClipTopAmount(this.clipTopAmount); + } + } + } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationChildrenContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationChildrenContainer.java index d7920a9b1e7b3..4b944d107a80b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationChildrenContainer.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationChildrenContainer.java @@ -412,7 +412,7 @@ public class NotificationChildrenContainer extends ViewGroup { * @param resultState the state to update * @param parentState the state of the parent */ - public void getState(StackScrollState resultState, StackViewState parentState) { + public void getState(StackScrollState resultState, ExpandableViewState parentState) { int childCount = mChildren.size(); int yPosition = mNotificationHeaderMargin; boolean firstChild = true; @@ -449,7 +449,7 @@ public class NotificationChildrenContainer extends ViewGroup { firstChild = false; } - StackViewState childState = resultState.getViewStateForView(child); + ExpandableViewState childState = resultState.getViewStateForView(child); int intrinsicHeight = child.getIntrinsicHeight(); if (childrenExpanded) { // When a group is expanded and moving into bottom stack, the bottom visible child @@ -530,7 +530,7 @@ public class NotificationChildrenContainer extends ViewGroup { * @return true if children after this one should be hidden. */ private boolean updateChildStateForExpandedGroup(ExpandableNotificationRow child, - int parentHeight, StackViewState childState, int yPosition) { + int parentHeight, ExpandableViewState childState, int yPosition) { final int top = yPosition + child.getClipTopAmount(); final int intrinsicHeight = child.getIntrinsicHeight(); final int bottom = top + intrinsicHeight; @@ -570,8 +570,8 @@ public class NotificationChildrenContainer extends ViewGroup { || mNotificationParent.isGroupExpansionChanging(); for (int i = 0; i < childCount; i++) { ExpandableNotificationRow child = mChildren.get(i); - StackViewState viewState = state.getViewStateForView(child); - state.applyState(child, viewState); + ExpandableViewState viewState = state.getViewStateForView(child); + viewState.applyToView(child); // layout the divider View divider = mDividers.get(i); @@ -584,16 +584,16 @@ public class NotificationChildrenContainer extends ViewGroup { } tmpState.hidden = !dividersVisible; tmpState.alpha = alpha; - state.applyViewState(divider, tmpState); + tmpState.applyToView(divider); // There is no fake shadow to be drawn on the children child.setFakeShadowIntensity(0.0f, 0.0f, 0, 0); } if (mOverflowNumber != null) { - state.applyViewState(mOverflowNumber, mGroupOverFlowState); + mGroupOverFlowState.applyToView(mOverflowNumber); mNeverAppliedGroupState = false; } if (mNotificationHeader != null) { - state.applyViewState(mNotificationHeader, mHeaderViewState); + mHeaderViewState.applyToView(mNotificationHeader); } } @@ -617,7 +617,7 @@ public class NotificationChildrenContainer extends ViewGroup { || mNotificationParent.isGroupExpansionChanging(); for (int i = childCount - 1; i >= 0; i--) { ExpandableNotificationRow child = mChildren.get(i); - StackViewState viewState = state.getViewStateForView(child); + ExpandableViewState viewState = state.getViewStateForView(child); stateAnimator.startStackAnimations(child, viewState, state, -1, baseDelay); // layout the divider @@ -639,7 +639,7 @@ public class NotificationChildrenContainer extends ViewGroup { if (mNeverAppliedGroupState) { float alpha = mGroupOverFlowState.alpha; mGroupOverFlowState.alpha = 0; - state.applyViewState(mOverflowNumber, mGroupOverFlowState); + mGroupOverFlowState.applyToView(mOverflowNumber); mGroupOverFlowState.alpha = alpha; mNeverAppliedGroupState = false; } @@ -647,7 +647,7 @@ public class NotificationChildrenContainer extends ViewGroup { baseDelay, duration); } if (mNotificationHeader != null) { - state.applyViewState(mNotificationHeader, mHeaderViewState); + mHeaderViewState.applyToView(mNotificationHeader); } } 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 72a0e5929a175..a8c082ee5fd68 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java @@ -541,15 +541,15 @@ public class NotificationStackScrollLayout extends ViewGroup * Returns the location the given child is currently rendered at. * * @param child the child to get the location for - * @return one of {@link StackViewState}'s LOCATION_* constants + * @return one of {@link ExpandableViewState}'s LOCATION_* constants */ public int getChildLocation(View child) { - StackViewState childViewState = mCurrentStackScrollState.getViewStateForView(child); + ExpandableViewState childViewState = mCurrentStackScrollState.getViewStateForView(child); if (childViewState == null) { - return StackViewState.LOCATION_UNKNOWN; + return ExpandableViewState.LOCATION_UNKNOWN; } if (childViewState.gone) { - return StackViewState.LOCATION_GONE; + return ExpandableViewState.LOCATION_GONE; } return childViewState.location; } @@ -1072,7 +1072,7 @@ public class NotificationStackScrollLayout extends ViewGroup row.getStatusBarNotification()); mGroupExpandedForMeasure = false; row.setForceUnlocked(false); - StackViewState viewState = mCurrentStackScrollState.getViewStateForView(view); + ExpandableViewState viewState = mCurrentStackScrollState.getViewStateForView(view); if (viewState != null) { // The view could have been removed return Math.min(viewState.height, maxContentHeight); @@ -2730,7 +2730,7 @@ public class NotificationStackScrollLayout extends ViewGroup row.setHeadsupDisappearRunning(false); } } else { - StackViewState viewState = mCurrentStackScrollState.getViewStateForView(row); + ExpandableViewState viewState = mCurrentStackScrollState.getViewStateForView(row); if (viewState == null) { // A view state was never generated for this view, so we don't need to animate // this. This may happen with notification children. @@ -2755,7 +2755,7 @@ public class NotificationStackScrollLayout extends ViewGroup mAddedHeadsUpChildren.clear(); } - private boolean shouldHunAppearFromBottom(StackViewState viewState) { + private boolean shouldHunAppearFromBottom(ExpandableViewState viewState) { if (viewState.yTranslation + viewState.height < mAmbientState.getMaxHeadsUpTranslation()) { return false; } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java index c9e4eacd6fdc1..3a6d757fe9dec 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java @@ -128,7 +128,7 @@ public class StackScrollAlgorithm { int childCount = algorithmState.visibleChildren.size(); for (int i = 0; i < childCount; i++) { View child = algorithmState.visibleChildren.get(i); - StackViewState childViewState = resultState.getViewStateForView(child); + ExpandableViewState childViewState = resultState.getViewStateForView(child); // The speed bump can also be gone, so equality needs to be taken when comparing // indices. @@ -144,7 +144,7 @@ public class StackScrollAlgorithm { int childCount = algorithmState.visibleChildren.size(); for (int i = 0; i < childCount; i++) { ExpandableView child = algorithmState.visibleChildren.get(i); - StackViewState state = resultState.getViewStateForView(child); + ExpandableViewState state = resultState.getViewStateForView(child); if (!child.mustStayOnScreen()) { previousNotificationEnd = Math.max(drawStart, previousNotificationEnd); previousNotificationStart = Math.max(drawStart, previousNotificationStart); @@ -195,7 +195,7 @@ public class StackScrollAlgorithm { int childCount = algorithmState.visibleChildren.size(); for (int i = 0; i < childCount; i++) { View child = algorithmState.visibleChildren.get(i); - StackViewState childViewState = resultState.getViewStateForView(child); + ExpandableViewState childViewState = resultState.getViewStateForView(child); childViewState.dimmed = dimmed; childViewState.dark = dark; childViewState.hideSensitive = hideSensitive; @@ -219,7 +219,7 @@ public class StackScrollAlgorithm { if (!draggedViews.contains(nextChild)) { // only if the view is not dragged itself we modify its state to be fully // visible - StackViewState viewState = resultState.getViewStateForView( + ExpandableViewState viewState = resultState.getViewStateForView( nextChild); // The child below the dragged one must be fully visible if (ambientState.isShadeExpanded()) { @@ -229,7 +229,7 @@ public class StackScrollAlgorithm { } // Lets set the alpha to the one it currently has, as its currently being dragged - StackViewState viewState = resultState.getViewStateForView(draggedView); + ExpandableViewState viewState = resultState.getViewStateForView(draggedView); // The dragged child should keep the set alpha viewState.alpha = draggedView.getAlpha(); } @@ -284,7 +284,7 @@ public class StackScrollAlgorithm { if (row.isSummaryWithChildren() && children != null) { for (ExpandableNotificationRow childRow : children) { if (childRow.getVisibility() != View.GONE) { - StackViewState childState + ExpandableViewState childState = resultState.getViewStateForView(childRow); childState.notGoneIndex = notGoneIndex; notGoneIndex++; @@ -300,7 +300,7 @@ public class StackScrollAlgorithm { private int updateNotGoneIndex(StackScrollState resultState, StackScrollAlgorithmState state, int notGoneIndex, ExpandableView v) { - StackViewState viewState = resultState.getViewStateForView(v); + ExpandableViewState viewState = resultState.getViewStateForView(v); viewState.notGoneIndex = notGoneIndex; state.visibleChildren.add(v); notGoneIndex++; @@ -336,8 +336,8 @@ public class StackScrollAlgorithm { StackScrollAlgorithmState algorithmState, AmbientState ambientState, float currentYPosition, float bottomStackStart) { ExpandableView child = algorithmState.visibleChildren.get(i); - StackViewState childViewState = resultState.getViewStateForView(child); - childViewState.location = StackViewState.LOCATION_UNKNOWN; + ExpandableViewState childViewState = resultState.getViewStateForView(child); + childViewState.location = ExpandableViewState.LOCATION_UNKNOWN; int paddingAfterChild = getPaddingAfterChild(algorithmState, child); int childHeight = getMaxAllowedChildHeight(child); int collapsedHeight = child.getCollapsedHeight(); @@ -367,7 +367,7 @@ public class StackScrollAlgorithm { } else { // Case 2: // We are in the regular scroll area. - childViewState.location = StackViewState.LOCATION_MAIN_AREA; + childViewState.location = ExpandableViewState.LOCATION_MAIN_AREA; clampPositionToBottomStackStart(childViewState, childViewState.height, childHeight, ambientState); } @@ -380,9 +380,9 @@ public class StackScrollAlgorithm { } currentYPosition = childViewState.yTranslation + childHeight + paddingAfterChild; if (currentYPosition <= 0) { - childViewState.location = StackViewState.LOCATION_HIDDEN_TOP; + childViewState.location = ExpandableViewState.LOCATION_HIDDEN_TOP; } - if (childViewState.location == StackViewState.LOCATION_UNKNOWN) { + if (childViewState.location == ExpandableViewState.LOCATION_UNKNOWN) { Log.wtf(LOG_TAG, "Failed to assign location for child " + i); } @@ -414,10 +414,10 @@ public class StackScrollAlgorithm { if (!row.isHeadsUp()) { break; } - StackViewState childState = resultState.getViewStateForView(row); + ExpandableViewState childState = resultState.getViewStateForView(row); if (topHeadsUpEntry == null) { topHeadsUpEntry = row; - childState.location = StackViewState.LOCATION_FIRST_HUN; + childState.location = ExpandableViewState.LOCATION_FIRST_HUN; } boolean isTopEntry = topHeadsUpEntry == row; float unmodifiedEndLocation = childState.yTranslation + childState.height; @@ -429,7 +429,7 @@ public class StackScrollAlgorithm { if (row.isPinned()) { childState.yTranslation = Math.max(childState.yTranslation, 0); childState.height = Math.max(row.getIntrinsicHeight(), childState.height); - StackViewState topState = resultState.getViewStateForView(topHeadsUpEntry); + ExpandableViewState topState = resultState.getViewStateForView(topHeadsUpEntry); if (!isTopEntry && (!mIsExpanded || unmodifiedEndLocation < topState.yTranslation + topState.height)) { // Ensure that a headsUp doesn't vertically extend further than the heads-up at @@ -443,7 +443,7 @@ public class StackScrollAlgorithm { } private void clampHunToTop(AmbientState ambientState, ExpandableNotificationRow row, - StackViewState childState) { + ExpandableViewState childState) { float newTranslation = Math.max(ambientState.getTopPadding() + ambientState.getStackTranslation(), childState.yTranslation); childState.height = (int) Math.max(childState.height - (newTranslation @@ -452,7 +452,7 @@ public class StackScrollAlgorithm { } private void clampHunToMaxTranslation(AmbientState ambientState, ExpandableNotificationRow row, - StackViewState childState) { + ExpandableViewState childState) { float newTranslation; float bottomPosition = ambientState.getMaxHeadsUpTranslation() - row.getCollapsedHeight(); newTranslation = Math.min(childState.yTranslation, bottomPosition); @@ -469,7 +469,7 @@ public class StackScrollAlgorithm { * @param childHeight the height of this child * @param minHeight the minumum Height of the View */ - private void clampPositionToBottomStackStart(StackViewState childViewState, + private void clampPositionToBottomStackStart(ExpandableViewState childViewState, int childHeight, int minHeight, AmbientState ambientState) { int bottomStackStart = ambientState.getInnerHeight() @@ -495,7 +495,7 @@ public class StackScrollAlgorithm { private void updateStateForChildTransitioningInBottom(StackScrollAlgorithmState algorithmState, float transitioningPositionStart, ExpandableView child, float currentYPosition, - StackViewState childViewState, int childHeight) { + ExpandableViewState childViewState, int childHeight) { // This is the transitioning element on top of bottom stack, calculate how far we are in. algorithmState.partialInBottom = 1.0f - ( @@ -514,11 +514,11 @@ public class StackScrollAlgorithm { } childViewState.yTranslation = transitioningPositionStart + offset - newHeight - getPaddingAfterChild(algorithmState, child); - childViewState.location = StackViewState.LOCATION_MAIN_AREA; + childViewState.location = ExpandableViewState.LOCATION_MAIN_AREA; } private void updateStateForChildFullyInBottomStack(StackScrollAlgorithmState algorithmState, - float transitioningPositionStart, StackViewState childViewState, + float transitioningPositionStart, ExpandableViewState childViewState, int collapsedHeight, AmbientState ambientState, ExpandableView child) { float currentYPosition; algorithmState.itemsInBottomStack += 1.0f; @@ -527,7 +527,7 @@ public class StackScrollAlgorithm { currentYPosition = transitioningPositionStart + mBottomStackIndentationFunctor.getValue(algorithmState.itemsInBottomStack) - getPaddingAfterChild(algorithmState, child); - childViewState.location = StackViewState.LOCATION_BOTTOM_STACK_PEEKING; + childViewState.location = ExpandableViewState.LOCATION_BOTTOM_STACK_PEEKING; } else { // we are fully inside the stack if (algorithmState.itemsInBottomStack > MAX_ITEMS_IN_BOTTOM_STACK + 2) { @@ -537,7 +537,7 @@ public class StackScrollAlgorithm { > MAX_ITEMS_IN_BOTTOM_STACK + 1) { childViewState.shadowAlpha = 1.0f - algorithmState.partialInBottom; } - childViewState.location = StackViewState.LOCATION_BOTTOM_STACK_HIDDEN; + childViewState.location = ExpandableViewState.LOCATION_BOTTOM_STACK_HIDDEN; currentYPosition = ambientState.getInnerHeight(); } childViewState.height = collapsedHeight; @@ -553,7 +553,7 @@ public class StackScrollAlgorithm { * @param childHeight the height of the child * @param ambientState The ambient state of the algorithm */ - protected void updateFirstChildHeight(ExpandableView child, StackViewState childViewState, + protected void updateFirstChildHeight(ExpandableView child, ExpandableViewState childViewState, int childHeight, AmbientState ambientState) { // The starting position of the bottom stack peek @@ -585,7 +585,7 @@ public class StackScrollAlgorithm { StackScrollState resultState, StackScrollAlgorithmState algorithmState, AmbientState ambientState) { ExpandableView child = algorithmState.visibleChildren.get(i); - StackViewState childViewState = resultState.getViewStateForView(child); + ExpandableViewState childViewState = resultState.getViewStateForView(child); if (i > (childCount - 1 - algorithmState.itemsInBottomStack)) { // We are in the bottom stack float numItemsAbove = i - (childCount - 1 - algorithmState.itemsInBottomStack); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollState.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollState.java index 8f0cd8e63ee0a..1dc09f1528395 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollState.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollState.java @@ -21,8 +21,6 @@ import android.view.View; import android.view.ViewGroup; import com.android.systemui.R; -import com.android.systemui.statusbar.DismissView; -import com.android.systemui.statusbar.EmptyShadeView; import com.android.systemui.statusbar.ExpandableNotificationRow; import com.android.systemui.statusbar.ExpandableView; @@ -38,14 +36,11 @@ public class StackScrollState { private static final String CHILD_NOT_FOUND_TAG = "StackScrollStateNoSuchChild"; private final ViewGroup mHostView; - private WeakHashMap mStateMap; - private final int mClearAllTopPadding; + private WeakHashMap mStateMap; public StackScrollState(ViewGroup hostView) { mHostView = hostView; mStateMap = new WeakHashMap<>(); - mClearAllTopPadding = hostView.getContext().getResources().getDimensionPixelSize( - R.dimen.clear_all_padding_top); } public ViewGroup getHostView() { @@ -73,9 +68,9 @@ public class StackScrollState { } private void resetViewState(ExpandableView view) { - StackViewState viewState = mStateMap.get(view); + ExpandableViewState viewState = mStateMap.get(view); if (viewState == null) { - viewState = new StackViewState(); + viewState = view.createNewViewState(this); mStateMap.put(view, viewState); } // initialize with the default values of the view @@ -87,7 +82,7 @@ public class StackScrollState { viewState.hidden = false; } - public StackViewState getViewStateForView(View requestedView) { + public ExpandableViewState getViewStateForView(View requestedView) { return mStateMap.get(requestedView); } @@ -103,130 +98,16 @@ public class StackScrollState { int numChildren = mHostView.getChildCount(); for (int i = 0; i < numChildren; i++) { ExpandableView child = (ExpandableView) mHostView.getChildAt(i); - StackViewState state = mStateMap.get(child); - if (!applyState(child, state)) { + ExpandableViewState state = mStateMap.get(child); + if (state == null) { + Log.wtf(CHILD_NOT_FOUND_TAG, "No child state was found when applying this state " + + "to the hostView"); continue; } - if (child instanceof DismissView) { - DismissView dismissView = (DismissView) child; - boolean visible = state.clipTopAmount < mClearAllTopPadding; - dismissView.performVisibilityAnimation(visible && !dismissView.willBeGone()); - } else if (child instanceof EmptyShadeView) { - EmptyShadeView emptyShadeView = (EmptyShadeView) child; - boolean visible = state.clipTopAmount <= 0; - emptyShadeView.performVisibilityAnimation( - visible && !emptyShadeView.willBeGone()); + if (state.gone) { + continue; } - } - } - - /** - * Applies a {@link StackViewState} to an {@link ExpandableView}. - * - * @return whether the state was applied correctly - */ - public boolean applyState(ExpandableView view, StackViewState state) { - if (state == null) { - Log.wtf(CHILD_NOT_FOUND_TAG, "No child state was found when applying this state " + - "to the hostView"); - return false; - } - if (state.gone) { - return false; - } - applyViewState(view, state); - - int height = view.getActualHeight(); - int newHeight = state.height; - - // apply height - if (height != newHeight) { - view.setActualHeight(newHeight, false /* notifyListeners */); - } - - float shadowAlpha = view.getShadowAlpha(); - float newShadowAlpha = state.shadowAlpha; - - // apply shadowAlpha - if (shadowAlpha != newShadowAlpha) { - view.setShadowAlpha(newShadowAlpha); - } - - // apply dimming - view.setDimmed(state.dimmed, false /* animate */); - - // apply hiding sensitive - view.setHideSensitive( - state.hideSensitive, false /* animated */, 0 /* delay */, 0 /* duration */); - - // apply speed bump state - view.setBelowSpeedBump(state.belowSpeedBump); - - // apply dark - view.setDark(state.dark, false /* animate */, 0 /* delay */); - - // apply clipping - float oldClipTopAmount = view.getClipTopAmount(); - if (oldClipTopAmount != state.clipTopAmount) { - view.setClipTopAmount(state.clipTopAmount); - } - if (view instanceof ExpandableNotificationRow) { - ExpandableNotificationRow row = (ExpandableNotificationRow) view; - if (state.isBottomClipped) { - row.setClipToActualHeight(true); - } - row.applyChildrenState(this); - } - return true; - } - - /** - * Applies a {@link ViewState} to a normal view. - */ - public void applyViewState(View view, ViewState state) { - float alpha = view.getAlpha(); - float yTranslation = view.getTranslationY(); - float xTranslation = view.getTranslationX(); - float zTranslation = view.getTranslationZ(); - float newAlpha = state.alpha; - float newYTranslation = state.yTranslation; - float newZTranslation = state.zTranslation; - boolean becomesInvisible = newAlpha == 0.0f || state.hidden; - if (alpha != newAlpha && xTranslation == 0) { - // apply layer type - boolean becomesFullyVisible = newAlpha == 1.0f; - boolean newLayerTypeIsHardware = !becomesInvisible && !becomesFullyVisible - && view.hasOverlappingRendering(); - int layerType = view.getLayerType(); - int newLayerType = newLayerTypeIsHardware - ? View.LAYER_TYPE_HARDWARE - : View.LAYER_TYPE_NONE; - if (layerType != newLayerType) { - view.setLayerType(newLayerType, null); - } - - // apply alpha - view.setAlpha(newAlpha); - } - - // apply visibility - int oldVisibility = view.getVisibility(); - int newVisibility = becomesInvisible ? View.INVISIBLE : View.VISIBLE; - if (newVisibility != oldVisibility) { - if (!(view instanceof ExpandableView) || !((ExpandableView) view).willBeGone()) { - // We don't want views to change visibility when they are animating to GONE - view.setVisibility(newVisibility); - } - } - - // apply yTranslation - if (yTranslation != newYTranslation) { - view.setTranslationY(newYTranslation); - } - - // apply zTranslation - if (zTranslation != newZTranslation) { - view.setTranslationZ(newZTranslation); + state.applyToView(child); } } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java index 3804b42dc5e4c..0009a04f18bd3 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java @@ -75,7 +75,7 @@ public class StackStateAnimator { private final Interpolator mHeadsUpAppearInterpolator; private final int mGoToFullShadeAppearingTranslation; - private final StackViewState mTmpState = new StackViewState(); + private final ExpandableViewState mTmpState = new ExpandableViewState(); public NotificationStackScrollLayout mHostLayout; private ArrayList mNewEvents = new ArrayList<>(); @@ -122,7 +122,7 @@ public class StackStateAnimator { for (int i = 0; i < childCount; i++) { final ExpandableView child = (ExpandableView) mHostLayout.getChildAt(i); - StackViewState viewState = finalState.getViewStateForView(child); + ExpandableViewState viewState = finalState.getViewStateForView(child); if (viewState == null || child.getVisibility() == View.GONE || applyWithoutAnimation(child, viewState, finalState)) { continue; @@ -145,7 +145,7 @@ public class StackStateAnimator { * * @return true if no animation should be performed */ - private boolean applyWithoutAnimation(ExpandableView child, StackViewState viewState, + private boolean applyWithoutAnimation(ExpandableView child, ExpandableViewState viewState, StackScrollState finalState) { if (mShadeExpanded) { return false; @@ -162,7 +162,7 @@ public class StackStateAnimator { // This is another headsUp which might move. Let's animate! return false; } - finalState.applyState(child, viewState); + viewState.applyToView(child); return true; } @@ -171,7 +171,7 @@ public class StackStateAnimator { for (int i = childCount - 1; i >= 0; i--) { final ExpandableView child = (ExpandableView) mHostLayout.getChildAt(i); - StackViewState viewState = finalState.getViewStateForView(child); + ExpandableViewState viewState = finalState.getViewStateForView(child); if (viewState == null || child.getVisibility() == View.GONE) { continue; } @@ -184,16 +184,16 @@ public class StackStateAnimator { /** - * Start an animation to the given {@link StackViewState}. + * Start an animation to the given {@link ExpandableViewState}. * * @param child the child to start the animation on - * @param viewState the {@link StackViewState} of the view to animate to + * @param viewState the {@link ExpandableViewState} of the view to animate to * @param finalState the final state after the animation * @param i the index of the view; only relevant if the view is the speed bump and is * ignored otherwise * @param fixedDelay a fixed delay if desired or -1 if the delay should be calculated */ - public void startStackAnimations(final ExpandableView child, StackViewState viewState, + public void startStackAnimations(final ExpandableView child, ExpandableViewState viewState, StackScrollState finalState, int i, long fixedDelay) { boolean wasAdded = mNewAddChildren.contains(child); long duration = mCurrentLength; @@ -270,7 +270,7 @@ public class StackStateAnimator { * Start an animation to a new {@link ViewState}. * * @param child the child to start the animation on - * @param viewState the {@link StackViewState} of the view to animate to + * @param viewState the {@link ExpandableViewState} of the view to animate to * @param delay a fixed delay * @param duration the duration of the animation */ @@ -319,7 +319,7 @@ public class StackStateAnimator { } } - private long calculateChildAnimationDelay(StackViewState viewState, + private long calculateChildAnimationDelay(ExpandableViewState viewState, StackScrollState finalState) { if (mAnimationFilter.hasDarkEvent) { return calculateDelayDark(viewState); @@ -374,7 +374,7 @@ public class StackStateAnimator { return minDelay; } - private long calculateDelayDark(StackViewState viewState) { + private long calculateDelayDark(ExpandableViewState viewState) { int referenceIndex; if (mAnimationFilter.darkAnimationOriginIndex == NotificationStackScrollLayout.AnimationEvent.DARK_ANIMATION_ORIGIN_INDEX_ABOVE) { @@ -388,14 +388,14 @@ public class StackStateAnimator { return Math.abs(referenceIndex - viewState.notGoneIndex) * ANIMATION_DELAY_PER_ELEMENT_DARK; } - private long calculateDelayGoToFullShade(StackViewState viewState) { + private long calculateDelayGoToFullShade(ExpandableViewState viewState) { float index = viewState.notGoneIndex; index = (float) Math.pow(index, 0.7f); return (long) (index * ANIMATION_DELAY_PER_ELEMENT_GO_TO_FULL_SHADE); } private void startShadowAlphaAnimation(final ExpandableView child, - StackViewState viewState, long duration, long delay) { + ExpandableViewState viewState, long duration, long delay) { Float previousStartValue = getChildTag(child, TAG_START_SHADOW_ALPHA); Float previousEndValue = getChildTag(child, TAG_END_SHADOW_ALPHA); float newEndValue = viewState.shadowAlpha; @@ -454,7 +454,7 @@ public class StackStateAnimator { } private void startHeightAnimation(final ExpandableView child, - StackViewState viewState, long duration, long delay) { + ExpandableViewState viewState, long duration, long delay) { Integer previousStartValue = getChildTag(child, TAG_START_HEIGHT); Integer previousEndValue = getChildTag(child, TAG_END_HEIGHT); int newEndValue = viewState.height; @@ -532,7 +532,7 @@ public class StackStateAnimator { } private void startInsetAnimation(final ExpandableView child, - StackViewState viewState, long duration, long delay) { + ExpandableViewState viewState, long duration, long delay) { Integer previousStartValue = getChildTag(child, TAG_START_TOP_INSET); Integer previousEndValue = getChildTag(child, TAG_END_TOP_INSET); int newEndValue = viewState.clipTopAmount; @@ -864,13 +864,13 @@ public class StackStateAnimator { NotificationStackScrollLayout.AnimationEvent.ANIMATION_TYPE_ADD) { // This item is added, initialize it's properties. - StackViewState viewState = finalState + ExpandableViewState viewState = finalState .getViewStateForView(changingView); if (viewState == null) { // The position for this child was never generated, let's continue. continue; } - finalState.applyState(changingView, viewState); + viewState.applyToView(changingView); mNewAddChildren.add(changingView); } else if (event.animationType == @@ -882,7 +882,7 @@ public class StackStateAnimator { // Find the amount to translate up. This is needed in order to understand the // direction of the remove animation (either downwards or upwards) - StackViewState viewState = finalState + ExpandableViewState viewState = finalState .getViewStateForView(event.viewAfterChangingView); int actualHeight = changingView.getActualHeight(); // upwards by default @@ -920,7 +920,7 @@ public class StackStateAnimator { } else if (event.animationType == NotificationStackScrollLayout .AnimationEvent.ANIMATION_TYPE_HEADS_UP_APPEAR) { // This item is added, initialize it's properties. - StackViewState viewState = finalState.getViewStateForView(changingView); + ExpandableViewState viewState = finalState.getViewStateForView(changingView); mTmpState.copyFrom(viewState); if (event.headsUpFromBottom) { mTmpState.yTranslation = mHeadsUpAppearHeightBottom; @@ -928,7 +928,7 @@ public class StackStateAnimator { mTmpState.yTranslation = -mTmpState.height; } mHeadsUpAppearChildren.add(changingView); - finalState.applyState(changingView, mTmpState); + mTmpState.applyToView(changingView); } else if (event.animationType == NotificationStackScrollLayout .AnimationEvent.ANIMATION_TYPE_HEADS_UP_DISAPPEAR || event.animationType == NotificationStackScrollLayout diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/ViewState.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/ViewState.java index 5beaac378b041..2fead7edb5ba0 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/ViewState.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/ViewState.java @@ -18,6 +18,8 @@ package com.android.systemui.statusbar.stack; import android.view.View; +import com.android.systemui.statusbar.ExpandableView; + /** * A state of a view. This can be used to apply a set of view properties to a view with * {@link com.android.systemui.statusbar.stack.StackScrollState} or start animations with @@ -46,4 +48,58 @@ public class ViewState { gone = view.getVisibility() == View.GONE; hidden = false; } + + /** + * Applies a {@link ViewState} to a normal view. + */ + public void applyToView(View view) { + if (this.gone) { + // don't do anything with it + return; + } + float alpha = view.getAlpha(); + float yTranslation = view.getTranslationY(); + float xTranslation = view.getTranslationX(); + float zTranslation = view.getTranslationZ(); + float newAlpha = this.alpha; + float newYTranslation = this.yTranslation; + float newZTranslation = this.zTranslation; + boolean becomesInvisible = newAlpha == 0.0f || this.hidden; + if (alpha != newAlpha && xTranslation == 0) { + // apply layer type + boolean becomesFullyVisible = newAlpha == 1.0f; + boolean newLayerTypeIsHardware = !becomesInvisible && !becomesFullyVisible + && view.hasOverlappingRendering(); + int layerType = view.getLayerType(); + int newLayerType = newLayerTypeIsHardware + ? View.LAYER_TYPE_HARDWARE + : View.LAYER_TYPE_NONE; + if (layerType != newLayerType) { + view.setLayerType(newLayerType, null); + } + + // apply alpha + view.setAlpha(newAlpha); + } + + // apply visibility + int oldVisibility = view.getVisibility(); + int newVisibility = becomesInvisible ? View.INVISIBLE : View.VISIBLE; + if (newVisibility != oldVisibility) { + if (!(view instanceof ExpandableView) || !((ExpandableView) view).willBeGone()) { + // We don't want views to change visibility when they are animating to GONE + view.setVisibility(newVisibility); + } + } + + // apply yTranslation + if (yTranslation != newYTranslation) { + view.setTranslationY(newYTranslation); + } + + // apply zTranslation + if (zTranslation != newZTranslation) { + view.setTranslationZ(newZTranslation); + } + } }