summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Lyn Han <lynhan@google.com> 2021-04-30 18:20:50 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2021-04-30 18:20:50 +0000
commit2c4f9ddaf940f32311285667562b893dcfcc1cc1 (patch)
treecb9a77715c8bd912fdb0fbee6fd98b491080a6cb
parente0f6dc071fb1c16189dec64980b561cb86ef935f (diff)
parent80a42c0fe1cc1d56ceca75c0c398e88174583c52 (diff)
Merge "New shelf shape, notification corner animations on scroll" into sc-dev
-rw-r--r--packages/SystemUI/res/values/dimens.xml3
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java62
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationBackgroundView.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationRoundnessManager.java56
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationRoundnessManagerTest.java12
6 files changed, 84 insertions, 56 deletions
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 5371b413f389..13c285f12393 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -181,6 +181,9 @@
<!-- Radius for notifications corners without adjacent notifications -->
<dimen name="notification_corner_radius">28dp</dimen>
+ <!-- Distance over which notification corner animations run, near the shelf while scrolling. -->
+ <dimen name="notification_corner_animation_distance">48dp</dimen>
+
<!-- Radius for notifications corners with adjacent notifications -->
<dimen name="notification_corner_radius_small">4dp</dimen>
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
index fb109f310e15..8f462fea0468 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
@@ -84,7 +84,7 @@ public class NotificationShelf extends ActivatableNotificationView implements
private int mCutoutHeight;
private int mGapHeight;
private int mIndexOfFirstViewInShelf = -1;
-
+ private float mCornerAnimationDistance;
private NotificationShelfController mController;
public NotificationShelf(Context context, AttributeSet attrs) {
@@ -104,6 +104,7 @@ public class NotificationShelf extends ActivatableNotificationView implements
setClipToPadding(false);
mShelfIcons.setIsStaticLayout(false);
setBottomRoundness(1.0f, false /* animate */);
+ setTopRoundness(1f, false /* animate */);
// Setting this to first in section to get the clipping to the top roundness correct. This
// value determines the way we are clipping to the top roundness of the overall shade
@@ -134,6 +135,8 @@ public class NotificationShelf extends ActivatableNotificationView implements
mIconSize = res.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_icon_size);
mHiddenShelfIconSize = res.getDimensionPixelOffset(R.dimen.hidden_shelf_icon_size);
mGapHeight = res.getDimensionPixelSize(R.dimen.qs_notification_padding);
+ mCornerAnimationDistance = res.getDimensionPixelSize(
+ R.dimen.notification_corner_animation_distance);
mShelfIcons.setInNotificationIconShelf(true);
if (!mShowNotificationShelf) {
@@ -256,7 +259,7 @@ public class NotificationShelf extends ActivatableNotificationView implements
boolean aboveShelf = ViewState.getFinalTranslationZ(child) > baseZHeight
|| child.isPinned();
boolean isLastChild = child == lastChild;
- float rowTranslationY = child.getTranslationY();
+ final float viewStart = child.getTranslationY();
final float inShelfAmount = updateShelfTransformation(i, child, scrollingFast,
expandingAnimated, isLastChild);
@@ -278,7 +281,7 @@ public class NotificationShelf extends ActivatableNotificationView implements
ExpandableNotificationRow expandableRow = (ExpandableNotificationRow) child;
numViewsInShelf += inShelfAmount;
int ownColorUntinted = expandableRow.getBackgroundColorWithoutTint();
- if (rowTranslationY >= shelfStart && mNotGoneIndex == -1) {
+ if (viewStart >= shelfStart && mNotGoneIndex == -1) {
mNotGoneIndex = notGoneIndex;
setTintColor(previousColor);
setOverrideTintColor(colorTwoBefore, transitionAmount);
@@ -317,26 +320,44 @@ public class NotificationShelf extends ActivatableNotificationView implements
notGoneIndex++;
}
+ final float viewEnd = viewStart + child.getActualHeight();
+ final float cornerAnimationDistance = mCornerAnimationDistance
+ * mAmbientState.getExpansionFraction();
+ final float cornerAnimationTop = shelfStart - cornerAnimationDistance;
+
if (child instanceof ActivatableNotificationView) {
ActivatableNotificationView anv =
(ActivatableNotificationView) child;
- if (anv.isFirstInSection() && previousAnv != null
- && previousAnv.isLastInSection()) {
- // If the top of the shelf is between the view before a gap and the view after a
- // gap then we need to adjust the shelf's top roundness.
- float distanceToGapBottom = child.getTranslationY() - getTranslationY();
- float distanceToGapTop = getTranslationY()
- - (previousAnv.getTranslationY() + previousAnv.getActualHeight());
- if (distanceToGapTop > 0) {
- // We interpolate our top roundness so that it's fully rounded if we're at
- // the bottom of the gap, and not rounded at all if we're at the top of the
- // gap (directly up against the bottom of previousAnv)
- // Then we apply the same roundness to the bottom of previousAnv so that the
- // corners join together as the shelf approaches previousAnv.
- firstElementRoundness = (float) Math.min(1.0,
- distanceToGapTop / mGapHeight);
- previousAnv.setBottomRoundness(firstElementRoundness,
- false /* don't animate */);
+
+ if (viewStart < shelfStart
+ && !mHostLayoutController.isViewAffectedBySwipe(anv)
+ && !mAmbientState.isPulsing()
+ && !mAmbientState.isDozing()) {
+
+ if (viewEnd >= cornerAnimationTop) {
+ // Round bottom corners within animation bounds
+ final float changeFraction = MathUtils.saturate(
+ (viewEnd - cornerAnimationTop) / cornerAnimationDistance);
+ final float roundness = anv.isLastInSection() ? 1f : changeFraction * 1f;
+ anv.setBottomRoundness(roundness, false);
+
+ } else if (viewEnd < cornerAnimationTop) {
+ // Fast scroll skips frames and leaves corners with unfinished rounding.
+ // Reset top and bottom corners outside of animation bounds.
+ anv.setBottomRoundness(anv.isLastInSection() ? 1f : 0f, false);
+ }
+
+ if (viewStart >= cornerAnimationTop) {
+ // Round top corners within animation bounds
+ final float changeFraction = MathUtils.saturate(
+ (viewStart - cornerAnimationTop) / cornerAnimationDistance);
+ final float roundness = anv.isFirstInSection() ? 1f : changeFraction * 1f;
+ anv.setTopRoundness(roundness, false);
+
+ } else if (viewStart < cornerAnimationTop) {
+ // Fast scroll skips frames and leaves corners with unfinished rounding.
+ // Reset top and bottom corners outside of animation bounds.
+ anv.setTopRoundness(anv.isFirstInSection() ? 1f : 0f, false);
}
}
previousAnv = anv;
@@ -394,7 +415,6 @@ public class NotificationShelf extends ActivatableNotificationView implements
private void setFirstElementRoundness(float firstElementRoundness) {
if (mFirstElementRoundness != firstElementRoundness) {
mFirstElementRoundness = firstElementRoundness;
- setTopRoundness(firstElementRoundness, false /* animate */);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationBackgroundView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationBackgroundView.java
index af8b4d99792a..f6ab409998bf 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationBackgroundView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationBackgroundView.java
@@ -84,8 +84,7 @@ public class NotificationBackgroundView extends View {
int bottom = mActualHeight;
if (mBottomIsRounded
&& mBottomAmountClips
- && !mExpandAnimationRunning
- && !mLastInSection) {
+ && !mExpandAnimationRunning) {
bottom -= mClipBottomAmount;
}
int left = 0;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationRoundnessManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationRoundnessManager.java
index b1ac12e84fb3..4b49e3a90ede 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationRoundnessManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationRoundnessManager.java
@@ -71,6 +71,13 @@ public class NotificationRoundnessManager {
}
}
+ public boolean isViewAffectedBySwipe(ExpandableView expandableView) {
+ return expandableView != null
+ && (expandableView == mSwipedView
+ || expandableView == mViewBeforeSwipedView
+ || expandableView == mViewAfterSwipedView);
+ }
+
boolean updateViewWithoutCallback(ExpandableView view,
boolean animate) {
if (view == null
@@ -78,38 +85,35 @@ public class NotificationRoundnessManager {
|| view == mViewAfterSwipedView) {
return false;
}
- float topRoundness = getRoundness(view, true /* top */);
- float bottomRoundness = getRoundness(view, false /* top */);
- boolean topChanged = view.setTopRoundness(topRoundness, animate);
- boolean bottomChanged = view.setBottomRoundness(bottomRoundness, animate);
- boolean firstInSection = isFirstInSection(view, false /* exclude first section */);
- boolean lastInSection = isLastInSection(view, false /* exclude last section */);
- view.setFirstInSection(firstInSection);
- view.setLastInSection(lastInSection);
- return (firstInSection || lastInSection) && (topChanged || bottomChanged);
+
+ final float topRoundness = getRoundness(view, true /* top */);
+ final float bottomRoundness = getRoundness(view, false /* top */);
+
+ final boolean topChanged = view.setTopRoundness(topRoundness, animate);
+ final boolean bottomChanged = view.setBottomRoundness(bottomRoundness, animate);
+
+ final boolean isFirstInSection = isFirstInSection(view);
+ final boolean isLastInSection = isLastInSection(view);
+
+ view.setFirstInSection(isFirstInSection);
+ view.setLastInSection(isLastInSection);
+
+ return (isFirstInSection || isLastInSection) && (topChanged || bottomChanged);
}
- private boolean isFirstInSection(ExpandableView view, boolean includeFirstSection) {
- int numNonEmptySections = 0;
+ private boolean isFirstInSection(ExpandableView view) {
for (int i = 0; i < mFirstInSectionViews.length; i++) {
if (view == mFirstInSectionViews[i]) {
- return includeFirstSection || numNonEmptySections > 0;
- }
- if (mFirstInSectionViews[i] != null) {
- numNonEmptySections++;
+ return true;
}
}
return false;
}
- private boolean isLastInSection(ExpandableView view, boolean includeLastSection) {
- int numNonEmptySections = 0;
+ private boolean isLastInSection(ExpandableView view) {
for (int i = mLastInSectionViews.length - 1; i >= 0; i--) {
if (view == mLastInSectionViews[i]) {
- return includeLastSection || numNonEmptySections > 0;
- }
- if (mLastInSectionViews[i] != null) {
- numNonEmptySections++;
+ return true;
}
}
return false;
@@ -172,10 +176,10 @@ public class NotificationRoundnessManager {
|| (view.isHeadsUpAnimatingAway()) && !mExpanded)) {
return 1.0f;
}
- if (isFirstInSection(view, true /* include first section */) && top) {
+ if (isFirstInSection(view) && top) {
return 1.0f;
}
- if (isLastInSection(view, true /* include last section */) && !top) {
+ if (isLastInSection(view) && !top) {
return 1.0f;
}
if (view == mTrackedHeadsUp) {
@@ -229,10 +233,8 @@ public class NotificationRoundnessManager {
: section.getLastVisibleChild());
if (newView == oldView) {
isStillPresent = true;
- if (oldView.isFirstInSection() != isFirstInSection(oldView,
- false /* exclude first section */)
- || oldView.isLastInSection() != isLastInSection(oldView,
- false /* exclude last section */)) {
+ if (oldView.isFirstInSection() != isFirstInSection(oldView)
+ || oldView.isLastInSection() != isLastInSection(oldView)) {
adjacentSectionChanged = true;
}
break;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
index ae9467eb651b..b039df3f32af 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
@@ -740,6 +740,10 @@ public class NotificationStackScrollLayoutController {
return true;
}
+ public boolean isViewAffectedBySwipe(ExpandableView expandableView) {
+ return mNotificationRoundnessManager.isViewAffectedBySwipe(expandableView);
+ }
+
public void addOnExpandedHeightChangedListener(BiConsumer<Float, Float> listener) {
mView.addOnExpandedHeightChangedListener(listener);
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationRoundnessManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationRoundnessManagerTest.java
index 919ddcb488c2..0772c03d10d0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationRoundnessManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationRoundnessManagerTest.java
@@ -315,8 +315,8 @@ public class NotificationRoundnessManagerTest extends SysuiTestCase {
@Test
public void testNoViewsFirstOrLastInSectionWhenSecondSectionEmpty() {
- Assert.assertFalse(mFirst.isFirstInSection());
- Assert.assertFalse(mFirst.isLastInSection());
+ Assert.assertTrue(mFirst.isFirstInSection());
+ Assert.assertTrue(mFirst.isLastInSection());
}
@Test
@@ -325,8 +325,8 @@ public class NotificationRoundnessManagerTest extends SysuiTestCase {
createSection(null, null),
createSection(mSecond, mSecond)
});
- Assert.assertFalse(mSecond.isFirstInSection());
- Assert.assertFalse(mSecond.isLastInSection());
+ Assert.assertTrue(mSecond.isFirstInSection());
+ Assert.assertTrue(mSecond.isLastInSection());
}
@Test
@@ -335,10 +335,10 @@ public class NotificationRoundnessManagerTest extends SysuiTestCase {
createSection(mFirst, mFirst),
createSection(mSecond, mSecond)
});
- Assert.assertFalse(mFirst.isFirstInSection());
+ Assert.assertTrue(mFirst.isFirstInSection());
Assert.assertTrue(mFirst.isLastInSection());
Assert.assertTrue(mSecond.isFirstInSection());
- Assert.assertFalse(mSecond.isLastInSection());
+ Assert.assertTrue(mSecond.isLastInSection());
}
private NotificationSection createSection(ExpandableNotificationRow first,