From ef8c2257045f73f0576c90c05c715c5f31ef81d8 Mon Sep 17 00:00:00 2001 From: Selim Cinek Date: Fri, 10 Feb 2017 14:52:18 -0800 Subject: [PATCH] Fixed an issue where children dissappeared the wrong way Because we were comparing relative to absolute positions, we need to calculate the next view the right way. Test: add children in group, remove the last / middle one Fixes: 35193074 Change-Id: I415a978b84d528ded402b99b872769b98aa49ec0 --- .../statusbar/ExpandableNotificationRow.java | 16 ++++++++- .../stack/NotificationStackScrollLayout.java | 36 ++++++++++++++++--- .../statusbar/stack/StackStateAnimator.java | 17 ++++++++- 3 files changed, 63 insertions(+), 6 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java index 6a5f79fdcd9ba..3bbaf998cc9af 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java @@ -211,6 +211,8 @@ public class ExpandableNotificationRow extends ActivatableNotificationView { private boolean mIsColorized; private boolean mUseIncreasedCollapsedHeight; private boolean mUseIncreasedHeadsUpHeight; + private float mTranslationWhenRemoved; + private boolean mWasChildInGroupWhenRemoved; @Override public boolean isGroupExpansionChanging() { @@ -836,10 +838,22 @@ public class ExpandableNotificationRow extends ActivatableNotificationView { public void setRemoved() { mRemoved = true; - + mTranslationWhenRemoved = getTranslationY(); + mWasChildInGroupWhenRemoved = isChildInGroup(); + if (isChildInGroup()) { + mTranslationWhenRemoved += getNotificationParent().getTranslationY(); + } mPrivateLayout.setRemoved(); } + public boolean wasChildInGroupWhenRemoved() { + return mWasChildInGroupWhenRemoved; + } + + public float getTranslationWhenRemoved() { + return mTranslationWhenRemoved; + } + public NotificationChildrenContainer getChildrenContainer() { return mChildrenContainer; } 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 dd4e876604f26..9057983d255e8 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java @@ -88,6 +88,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.HashSet; +import java.util.List; /** * A layout which handles a dynamic amount of notifications and presents them in a scrollable stack. @@ -1836,12 +1837,29 @@ public class NotificationStackScrollLayout extends ViewGroup * @return The first child which has visibility unequal to GONE which is currently below the * given translationY or equal to it. */ - private View getFirstChildBelowTranlsationY(float translationY) { + private View getFirstChildBelowTranlsationY(float translationY, boolean ignoreChildren) { int childCount = getChildCount(); for (int i = 0; i < childCount; i++) { View child = getChildAt(i); - if (child.getVisibility() != View.GONE && child.getTranslationY() >= translationY) { + if (child.getVisibility() == View.GONE) { + continue; + } + float rowTranslation = child.getTranslationY(); + if (rowTranslation >= translationY) { return child; + } else if (!ignoreChildren && child instanceof ExpandableNotificationRow) { + ExpandableNotificationRow row = (ExpandableNotificationRow) child; + if (row.isSummaryWithChildren() && row.areChildrenExpanded()) { + List notificationChildren = + row.getNotificationChildren(); + for (int childIndex = 0; childIndex < notificationChildren.size(); + childIndex++) { + ExpandableNotificationRow rowChild = notificationChildren.get(childIndex); + if (rowChild.getTranslationY() + rowTranslation >= translationY) { + return rowChild; + } + } + } } } return null; @@ -2500,7 +2518,7 @@ public class NotificationStackScrollLayout extends ViewGroup View groupParentWhenDismissed = row.getGroupParentWhenDismissed(); nextView = getFirstChildBelowTranlsationY(groupParentWhenDismissed != null ? groupParentWhenDismissed.getTranslationY() - : view.getTranslationY()); + : view.getTranslationY(), true /* ignoreChildren */); } if (nextView != null) { nextView.requestAccessibilityFocus(); @@ -2940,7 +2958,17 @@ public class NotificationStackScrollLayout extends ViewGroup AnimationEvent event = new AnimationEvent(child, animationType); // we need to know the view after this one - event.viewAfterChangingView = getFirstChildBelowTranlsationY(child.getTranslationY()); + float removedTranslation = child.getTranslationY(); + boolean ignoreChildren = true; + if (child instanceof ExpandableNotificationRow) { + ExpandableNotificationRow row = (ExpandableNotificationRow) child; + if (row.isRemoved() && row.wasChildInGroupWhenRemoved()) { + removedTranslation = row.getTranslationWhenRemoved(); + ignoreChildren = false; + } + } + event.viewAfterChangingView = getFirstChildBelowTranlsationY(removedTranslation, + ignoreChildren); mAnimationEvents.add(event); mSwipedOutViews.remove(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 55085e58c213f..98934341b41e6 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java @@ -389,10 +389,25 @@ public class StackStateAnimator { // upwards by default float translationDirection = -1.0f; if (viewState != null) { + float ownPosition = changingView.getTranslationY(); + if (changingView instanceof ExpandableNotificationRow + && event.viewAfterChangingView instanceof ExpandableNotificationRow) { + ExpandableNotificationRow changingRow = + (ExpandableNotificationRow) changingView; + ExpandableNotificationRow nextRow = + (ExpandableNotificationRow) event.viewAfterChangingView; + if (changingRow.isRemoved() + && changingRow.wasChildInGroupWhenRemoved() + && !nextRow.isChildInGroup()) { + // the next row isn't actually a child from a group! Let's + // compare absolute positions! + ownPosition = changingRow.getTranslationWhenRemoved(); + } + } // there was a view after this one, Approximate the distance the next child // travelled translationDirection = ((viewState.yTranslation - - (changingView.getTranslationY() + actualHeight / 2.0f)) * 2 / + - (ownPosition + actualHeight / 2.0f)) * 2 / actualHeight); translationDirection = Math.max(Math.min(translationDirection, 1.0f),-1.0f);