diff options
5 files changed, 102 insertions, 46 deletions
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml index 09d352971e16..e245c2422b86 100644 --- a/packages/SystemUI/res/values/dimens.xml +++ b/packages/SystemUI/res/values/dimens.xml @@ -301,6 +301,9 @@ <!-- The height of the divider between the individual notifications. --> <dimen name="notification_divider_height">0.5dp</dimen> + <!-- The height of the divider between the individual notifications when the notification wants it to be increased. This is currently the case for notification groups --> + <dimen name="notification_divider_height_increased">6dp</dimen> + <!-- The minimum amount of top overscroll to go to the quick settings. --> <dimen name="min_top_overscroll_to_qs">36dp</dimen> diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java index 93be009c29fd..6fae3abb513f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java @@ -1126,6 +1126,11 @@ public class ExpandableNotificationRow extends ActivatableNotificationView { } @Override + public boolean needsIncreasedPadding() { + return mIsSummaryWithChildren && isGroupExpanded(); + } + + @Override protected boolean disallowSingleClick(MotionEvent event) { float x = event.getX(); float y = event.getY(); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java index 2df6e5ef9204..a0fb34aecbf9 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java @@ -395,6 +395,10 @@ public abstract class ExpandableView extends FrameLayout { public void setShadowAlpha(float shadowAlpha) { } + public boolean needsIncreasedPadding() { + return false; + } + /** * A listener notifying when {@link #getActualHeight} changes. */ 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 a6f468f70901..d5b57ac0a018 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java @@ -121,7 +121,7 @@ public class NotificationStackScrollLayout extends ViewGroup private int mBottomStackSlowDownHeight; private int mBottomStackPeekSize; private int mPaddingBetweenElements; - private int mPaddingBetweenElementsNormal; + private int mIncreasedPaddingBetweenElements; private int mTopPadding; private int mCollapseSecondCardPadding; @@ -367,9 +367,11 @@ public class NotificationStackScrollLayout extends ViewGroup mBottomStackPeekSize = context.getResources() .getDimensionPixelSize(R.dimen.bottom_stack_peek_amount); mStackScrollAlgorithm.initView(context); - mPaddingBetweenElementsNormal = Math.max(1, context.getResources() + mPaddingBetweenElements = Math.max(1, context.getResources() .getDimensionPixelSize(R.dimen.notification_divider_height)); - mPaddingBetweenElements = mPaddingBetweenElementsNormal; + mIncreasedPaddingBetweenElements = context.getResources() + .getDimensionPixelSize(R.dimen.notification_divider_height_increased); + mBottomStackSlowDownHeight = mStackScrollAlgorithm.getBottomStackSlowDownLength(); mMinTopOverScrollToEscape = getResources().getDimensionPixelSize( R.dimen.min_top_overscroll_to_qs); @@ -1445,17 +1447,19 @@ public class NotificationStackScrollLayout extends ViewGroup private void updateContentHeight() { int height = 0; + boolean previousNeedsIncreasedPaddings = false; for (int i = 0; i < getChildCount(); i++) { - View child = getChildAt(i); - if (child.getVisibility() != View.GONE) { + ExpandableView expandableView = (ExpandableView) getChildAt(i); + if (expandableView.getVisibility() != View.GONE) { + boolean needsIncreasedPaddings = expandableView.needsIncreasedPadding(); if (height != 0) { - // add the padding before this element - height += mPaddingBetweenElements; - } - if (child instanceof ExpandableView) { - ExpandableView expandableView = (ExpandableView) child; - height += expandableView.getIntrinsicHeight(); + int padding = needsIncreasedPaddings || previousNeedsIncreasedPaddings + ? mIncreasedPaddingBetweenElements + : mPaddingBetweenElements; + height += padding; } + previousNeedsIncreasedPaddings = needsIncreasedPaddings; + height += expandableView.getIntrinsicHeight(); } } mContentHeight = height + mTopPadding; @@ -1911,7 +1915,7 @@ public class NotificationStackScrollLayout extends ViewGroup } ((ExpandableView) child).setOnHeightChangedListener(null); mCurrentStackScrollState.removeViewStateForView(child); - updateScrollStateForRemovedChild(child); + updateScrollStateForRemovedChild((ExpandableView) child); boolean animationGenerated = generateRemoveAnimation(child); if (animationGenerated && !mSwipedOutViews.contains(child)) { // Add this view to an overlay in order to ensure that it will still be temporary @@ -2010,9 +2014,12 @@ public class NotificationStackScrollLayout extends ViewGroup * * @param removedChild the removed child */ - private void updateScrollStateForRemovedChild(View removedChild) { + private void updateScrollStateForRemovedChild(ExpandableView removedChild) { int startingPosition = getPositionInLinearLayout(removedChild); - int childHeight = getIntrinsicHeight(removedChild) + mPaddingBetweenElements; + int padding = removedChild.needsIncreasedPadding() + ? mIncreasedPaddingBetweenElements : + mPaddingBetweenElements; + int childHeight = getIntrinsicHeight(removedChild) + padding; int endPosition = startingPosition + childHeight; if (endPosition <= mOwnScrollY) { // This child is fully scrolled of the top, so we have to deduct its height from the @@ -2035,16 +2042,25 @@ public class NotificationStackScrollLayout extends ViewGroup private int getPositionInLinearLayout(View requestedChild) { int position = 0; + boolean previousNeedsIncreasedPaddings = false; for (int i = 0; i < getChildCount(); i++) { - View child = getChildAt(i); + ExpandableView child = (ExpandableView) getChildAt(i); + boolean notGone = child.getVisibility() != View.GONE; + if (notGone) { + boolean needsIncreasedPaddings = child.needsIncreasedPadding(); + if (position != 0) { + int padding = needsIncreasedPaddings || previousNeedsIncreasedPaddings + ? mIncreasedPaddingBetweenElements : + mPaddingBetweenElements; + position += padding; + } + previousNeedsIncreasedPaddings = needsIncreasedPaddings; + } if (child == requestedChild) { return position; } - if (child.getVisibility() != View.GONE) { + if (notGone) { position += getIntrinsicHeight(child); - if (i < getChildCount()-1) { - position += mPaddingBetweenElements; - } } } return 0; @@ -3014,7 +3030,7 @@ public class NotificationStackScrollLayout extends ViewGroup } public int getDismissViewHeight() { - int height = mDismissView.getHeight() + mPaddingBetweenElementsNormal; + int height = mDismissView.getHeight() + mPaddingBetweenElements; // Hack: Accommodate for additional distance when we only have one notification and the // dismiss all button. 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 6b71e29a950c..f6959f0dfcbb 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java @@ -26,6 +26,7 @@ import com.android.systemui.statusbar.ExpandableNotificationRow; import com.android.systemui.statusbar.ExpandableView; import java.util.ArrayList; +import java.util.HashSet; import java.util.List; /** @@ -41,6 +42,7 @@ public class StackScrollAlgorithm { private static final int MAX_ITEMS_IN_TOP_STACK = 3; private int mPaddingBetweenElements; + private int mIncreasedPaddingBetweenElements; private int mCollapsedSize; private int mTopStackPeekSize; private int mBottomStackPeekSize; @@ -57,7 +59,6 @@ public class StackScrollAlgorithm { private ExpandableView mFirstChildWhileExpanding; private boolean mExpandedOnStart; private int mTopStackTotalSize; - private int mPaddingBetweenElementsNormal; private int mBottomStackSlowDownLength; private int mTopStackSlowDownLength; private int mCollapseSecondCardPadding; @@ -74,7 +75,6 @@ public class StackScrollAlgorithm { } private void updatePadding() { - mPaddingBetweenElements = mPaddingBetweenElementsNormal; mTopStackTotalSize = mTopStackSlowDownLength + mPaddingBetweenElements + mTopStackPeekSize; mTopStackIndentationFunctor = new PiecewiseLinearIndentationFunctor( @@ -94,8 +94,10 @@ public class StackScrollAlgorithm { } private void initConstants(Context context) { - mPaddingBetweenElementsNormal = Math.max(1, context.getResources() + mPaddingBetweenElements = Math.max(1, context.getResources() .getDimensionPixelSize(R.dimen.notification_divider_height)); + mIncreasedPaddingBetweenElements = context.getResources() + .getDimensionPixelSize(R.dimen.notification_divider_height_increased); mCollapsedSize = context.getResources() .getDimensionPixelSize(R.dimen.notification_min_height); mTopStackPeekSize = context.getResources() @@ -137,7 +139,7 @@ public class StackScrollAlgorithm { scrollY = Math.max(0, scrollY); algorithmState.scrollY = (int) (scrollY + mFirstChildMinHeight + bottomOverScroll); - updateVisibleChildren(resultState, algorithmState); + initAlgorithmState(resultState, algorithmState); // Phase 1: findNumberOfItemsInTopStackAndUpdateState(resultState, algorithmState, ambientState); @@ -310,19 +312,28 @@ public class StackScrollAlgorithm { } /** - * Update the visible children on the state. + * Initialize the algorithm state like updating the visible children. */ - private void updateVisibleChildren(StackScrollState resultState, + private void initAlgorithmState(StackScrollState resultState, StackScrollAlgorithmState state) { ViewGroup hostView = resultState.getHostView(); int childCount = hostView.getChildCount(); state.visibleChildren.clear(); state.visibleChildren.ensureCapacity(childCount); + state.increasedPaddingSet.clear(); int notGoneIndex = 0; + ExpandableView lastView = null; for (int i = 0; i < childCount; i++) { ExpandableView v = (ExpandableView) hostView.getChildAt(i); if (v.getVisibility() != View.GONE) { notGoneIndex = updateNotGoneIndex(resultState, state, notGoneIndex, v); + boolean needsIncreasedPadding = v.needsIncreasedPadding(); + if (needsIncreasedPadding) { + state.increasedPaddingSet.add(v); + if (lastView != null) { + state.increasedPaddingSet.add(lastView); + } + } if (v instanceof ExpandableNotificationRow) { ExpandableNotificationRow row = (ExpandableNotificationRow) v; @@ -340,6 +351,7 @@ public class StackScrollAlgorithm { } } } + lastView = v; } } } @@ -380,15 +392,17 @@ public class StackScrollAlgorithm { int numberOfElementsCompletelyIn = algorithmState.partialInTop == 1.0f ? algorithmState.lastTopStackIndex : (int) algorithmState.itemsInTopStack; + int paddingAfterChild; for (int i = 0; i < childCount; i++) { ExpandableView child = algorithmState.visibleChildren.get(i); StackViewState childViewState = resultState.getViewStateForView(child); childViewState.location = StackViewState.LOCATION_UNKNOWN; + paddingAfterChild = getPaddingAfterChild(algorithmState, child); int childHeight = getMaxAllowedChildHeight(child); int minHeight = child.getMinHeight(); float yPositionInScrollViewAfterElement = yPositionInScrollView + childHeight - + mPaddingBetweenElements; + + paddingAfterChild; float scrollOffset = yPositionInScrollView - algorithmState.scrollY + mFirstChildMinHeight; @@ -403,20 +417,20 @@ public class StackScrollAlgorithm { // The y position after this element float nextYPosition = currentYPosition + childHeight + - mPaddingBetweenElements; + paddingAfterChild; if (i <= algorithmState.lastTopStackIndex) { // Case 1: // We are in the top Stack - updateStateForTopStackChild(algorithmState, + updateStateForTopStackChild(algorithmState, child, numberOfElementsCompletelyIn, i, childHeight, childViewState, scrollOffset); clampPositionToTopStackEnd(childViewState, childHeight); // check if we are overlapping with the bottom stack - if (childViewState.yTranslation + childHeight + mPaddingBetweenElements + if (childViewState.yTranslation + childHeight + paddingAfterChild >= bottomStackStart && !mIsExpansionChanging && i != 0) { // we just collapse this element slightly - int newSize = (int) Math.max(bottomStackStart - mPaddingBetweenElements - + int newSize = (int) Math.max(bottomStackStart - paddingAfterChild - childViewState.yTranslation, minHeight); childViewState.height = newSize; updateStateForChildTransitioningInBottom(algorithmState, bottomStackStart, @@ -432,7 +446,7 @@ public class StackScrollAlgorithm { // According to the regular scroll view we are fully translated out of the // bottom of the screen so we are fully in the bottom stack updateStateForChildFullyInBottomStack(algorithmState, - bottomStackStart, childViewState, minHeight, ambientState); + bottomStackStart, childViewState, minHeight, ambientState, child); } else { // According to the regular scroll view we are currently translating out of / // into the bottom of the screen @@ -464,7 +478,7 @@ public class StackScrollAlgorithm { if (childViewState.location == StackViewState.LOCATION_UNKNOWN) { Log.wtf(LOG_TAG, "Failed to assign location for child " + i); } - currentYPosition = childViewState.yTranslation + childHeight + mPaddingBetweenElements; + currentYPosition = childViewState.yTranslation + childHeight + paddingAfterChild; yPositionInScrollView = yPositionInScrollViewAfterElement; childViewState.yTranslation += ambientState.getTopPadding() @@ -473,6 +487,13 @@ public class StackScrollAlgorithm { updateHeadsUpStates(resultState, algorithmState, ambientState); } + private int getPaddingAfterChild(StackScrollAlgorithmState algorithmState, + ExpandableView child) { + return algorithmState.increasedPaddingSet.contains(child) + ? mIncreasedPaddingBetweenElements + : mPaddingBetweenElements; + } + private void updateHeadsUpStates(StackScrollState resultState, StackScrollAlgorithmState algorithmState, AmbientState ambientState) { int childCount = algorithmState.visibleChildren.size(); @@ -576,7 +597,7 @@ public class StackScrollAlgorithm { // This is the transitioning element on top of bottom stack, calculate how far we are in. algorithmState.partialInBottom = 1.0f - ( (transitioningPositionStart - currentYPosition) / (childHeight + - mPaddingBetweenElements)); + getPaddingAfterChild(algorithmState, child))); // the offset starting at the transitionPosition of the bottom stack float offset = mBottomStackIndentationFunctor.getValue(algorithmState.partialInBottom); @@ -584,12 +605,12 @@ public class StackScrollAlgorithm { int newHeight = childHeight; if (childHeight > child.getMinHeight()) { newHeight = (int) Math.max(Math.min(transitioningPositionStart + offset - - mPaddingBetweenElements - currentYPosition, childHeight), + getPaddingAfterChild(algorithmState, child) - currentYPosition, childHeight), child.getMinHeight()); childViewState.height = newHeight; } childViewState.yTranslation = transitioningPositionStart + offset - newHeight - - mPaddingBetweenElements; + - getPaddingAfterChild(algorithmState, child); // We want at least to be at the end of the top stack when collapsing clampPositionToTopStackEnd(childViewState, newHeight); @@ -598,14 +619,14 @@ public class StackScrollAlgorithm { private void updateStateForChildFullyInBottomStack(StackScrollAlgorithmState algorithmState, float transitioningPositionStart, StackViewState childViewState, - int minHeight, AmbientState ambientState) { + int minHeight, AmbientState ambientState, ExpandableView child) { float currentYPosition; algorithmState.itemsInBottomStack += 1.0f; if (algorithmState.itemsInBottomStack < MAX_ITEMS_IN_BOTTOM_STACK) { // We are visually entering the bottom stack currentYPosition = transitioningPositionStart + mBottomStackIndentationFunctor.getValue(algorithmState.itemsInBottomStack) - - mPaddingBetweenElements; + - getPaddingAfterChild(algorithmState, child); childViewState.location = StackViewState.LOCATION_BOTTOM_STACK_PEEKING; } else { // we are fully inside the stack @@ -625,7 +646,7 @@ public class StackScrollAlgorithm { } private void updateStateForTopStackChild(StackScrollAlgorithmState algorithmState, - int numberOfElementsCompletelyIn, int i, int childHeight, + ExpandableView child, int numberOfElementsCompletelyIn, int i, int childHeight, StackViewState childViewState, float scrollOffset) { @@ -636,10 +657,11 @@ public class StackScrollAlgorithm { if (paddedIndex >= 0) { // We are currently visually entering the top stack - float distanceToStack = (childHeight + mPaddingBetweenElements) + float distanceToStack = (childHeight + getPaddingAfterChild(algorithmState, child)) - algorithmState.scrolledPixelsTop; if (i == algorithmState.lastTopStackIndex - && distanceToStack > (mTopStackTotalSize + mPaddingBetweenElements)) { + && distanceToStack > (mTopStackTotalSize + + getPaddingAfterChild(algorithmState, child))) { // Child is currently translating into stack but not yet inside slow down zone. // Handle it like the regular scrollview. @@ -649,7 +671,8 @@ public class StackScrollAlgorithm { float numItemsBefore; if (i == algorithmState.lastTopStackIndex) { numItemsBefore = 1.0f - - (distanceToStack / (mTopStackTotalSize + mPaddingBetweenElements)); + - (distanceToStack / (mTopStackTotalSize + + getPaddingAfterChild(algorithmState, child))); } else { numItemsBefore = algorithmState.itemsInTopStack - i; } @@ -686,15 +709,15 @@ public class StackScrollAlgorithm { // The y Position if the element would be in a regular scrollView float yPositionInScrollView = 0.0f; int childCount = algorithmState.visibleChildren.size(); - // find the number of elements in the top stack. for (int i = 0; i < childCount; i++) { ExpandableView child = algorithmState.visibleChildren.get(i); StackViewState childViewState = resultState.getViewStateForView(child); int childHeight = getMaxAllowedChildHeight(child); + int paddingAfterChild = getPaddingAfterChild(algorithmState, child); float yPositionInScrollViewAfterElement = yPositionInScrollView + childHeight - + mPaddingBetweenElements; + + paddingAfterChild; if (yPositionInScrollView < algorithmState.scrollY) { if (i == 0 && algorithmState.scrollY <= mFirstChildMinHeight) { @@ -722,7 +745,7 @@ public class StackScrollAlgorithm { algorithmState.scrolledPixelsTop = algorithmState.scrollY - yPositionInScrollView; algorithmState.partialInTop = (algorithmState.scrolledPixelsTop) / (childHeight - + mPaddingBetweenElements); + + paddingAfterChild); // Our element can be expanded, so this can get negative algorithmState.partialInTop = Math.max(0.0f, algorithmState.partialInTop); @@ -731,7 +754,7 @@ public class StackScrollAlgorithm { if (i == 0) { // If it is expanded we have to collapse it to a new size float newSize = yPositionInScrollViewAfterElement - - mPaddingBetweenElements + - paddingAfterChild - algorithmState.scrollY + mFirstChildMinHeight; newSize = Math.max(mFirstChildMinHeight, newSize); algorithmState.itemsInTopStack = 1.0f; @@ -932,6 +955,11 @@ public class StackScrollAlgorithm { * The children from the host view which are not gone. */ public final ArrayList<ExpandableView> visibleChildren = new ArrayList<ExpandableView>(); + + /** + * The children from the host that need an increased padding after them. + */ + public final HashSet<ExpandableView> increasedPaddingSet = new HashSet<>(); } } |