Clipping to the top roundness when scrolling
We are now clipping properly to the top roundness,
such that the scrolling works properly and you never
see a hard edge on the top.
Test: add notifications, scroll, observe nice clipping
Bug: 69168591
Change-Id: I991eb33337eee8f0e1cee56e01e4e457146cb145
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableOutlineView.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableOutlineView.java
index 8a3645a..66b3a75 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableOutlineView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableOutlineView.java
@@ -58,6 +58,7 @@
private static final Path EMPTY_PATH = new Path();
private final Rect mOutlineRect = new Rect();
+ private final Path mClipPath = new Path();
private boolean mCustomOutline;
private float mOutlineAlpha = -1f;
private float mOutlineRadius;
@@ -75,6 +76,8 @@
* it is moved. Otherwise, the translation is set on the {@code ExpandableOutlineView} itself.
*/
protected boolean mShouldTranslateContents;
+ private boolean mClipRoundedToClipTopAmount;
+ private float mDistanceToTopRoundness = -1;
private final ViewOutlineProvider mProvider = new ViewOutlineProvider() {
@Override
@@ -159,8 +162,8 @@
return roundedRectPath;
}
- private void getRoundedRectPath(int left, int top, int right, int bottom, float topRoundness,
- float bottomRoundness, Path outPath) {
+ public static void getRoundedRectPath(int left, int top, int right, int bottom,
+ float topRoundness, float bottomRoundness, Path outPath) {
outPath.reset();
int width = right - left;
float topRoundnessX = topRoundness;
@@ -197,20 +200,50 @@
@Override
protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
canvas.save();
+ Path intersectPath = null;
+ if (mClipRoundedToClipTopAmount) {
+ int left = 0;
+ int top = (int) (mClipTopAmount - mDistanceToTopRoundness);
+ int right = getWidth();
+ int bottom = (int) Math.max(getActualHeight() - mClipBottomAmount,
+ top + mOutlineRadius);
+ ExpandableOutlineView.getRoundedRectPath(left, top, right, bottom, mOutlineRadius,
+ 0.0f,
+ mClipPath);
+ intersectPath = mClipPath;
+ }
+ boolean clipped = false;
if (childNeedsClipping(child)) {
Path clipPath = getCustomClipPath(child);
if (clipPath == null) {
clipPath = getClipPath();
}
if (clipPath != null) {
+ if (intersectPath != null) {
+ clipPath.op(intersectPath, Path.Op.INTERSECT);
+ }
canvas.clipPath(clipPath);
+ clipped = true;
}
}
+ if (!clipped && intersectPath != null) {
+ canvas.clipPath(intersectPath);
+ }
boolean result = super.drawChild(canvas, child, drawingTime);
canvas.restore();
return result;
}
+ @Override
+ public void setDistanceToTopRoundness(float distanceToTopRoundness) {
+ super.setDistanceToTopRoundness(distanceToTopRoundness);
+ if (distanceToTopRoundness != mDistanceToTopRoundness) {
+ mClipRoundedToClipTopAmount = distanceToTopRoundness >= 0;
+ mDistanceToTopRoundness = distanceToTopRoundness;
+ invalidate();
+ }
+ }
+
protected boolean childNeedsClipping(View child) {
return false;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java
index f762513..eafa825 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java
@@ -130,6 +130,14 @@
}
}
+ /**
+ * Set the distance to the top roundness, from where we should start clipping a value above
+ * or equal to 0 is the effective distance, and if a value below 0 is received, there should
+ * be no clipping.
+ */
+ public void setDistanceToTopRoundness(float distanceToTopRoundness) {
+ }
+
public void setActualHeight(int actualHeight) {
setActualHeight(actualHeight, true /* notifyListeners */);
}
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 1d2baf1..6350107 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
@@ -657,11 +657,32 @@
private void onPreDrawDuringAnimation() {
mShelf.updateAppearance();
+ updateClippingToTopRoundedCorner();
if (!mNeedsAnimation && !mChildrenUpdateRequested) {
updateBackground();
}
}
+ private void updateClippingToTopRoundedCorner() {
+ Float clipStart = (float) mTopPadding;
+ Float clipEnd = clipStart + mCornerRadius;
+ boolean first = true;
+ for (int i = 0; i < getChildCount(); i++) {
+ ExpandableView child = (ExpandableView) getChildAt(i);
+ if (child.getVisibility() == GONE) {
+ continue;
+ }
+ float start = child.getTranslationY();
+ float end = start + Math.max(child.getActualHeight() - child.getClipBottomAmount(),
+ 0);
+ boolean clip = clipStart > start && clipStart < end
+ || clipEnd >= start && clipEnd <= end;
+ clip &= !(first && mOwnScrollY == 0);
+ child.setDistanceToTopRoundness(clip ? Math.max(start - clipStart, 0) : -1);
+ first = false;
+ }
+ }
+
private void updateScrollStateForAddedChildren() {
if (mChildrenToAddAnimated.isEmpty()) {
return;
@@ -2981,6 +3002,7 @@
mAnimationEvents.clear();
updateBackground();
updateViewShadows();
+ updateClippingToTopRoundedCorner();
} else {
applyCurrentState();
}
@@ -3674,6 +3696,7 @@
setAnimationRunning(false);
updateBackground();
updateViewShadows();
+ updateClippingToTopRoundedCorner();
}
private void updateViewShadows() {